<template>
  <div class="font-inter bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-50 text-dark min-h-screen flex" style="font-family: 'Inter', sans-serif; background: linear-gradient(135deg, #f8fafc 0%, #e0f2fe 50%, #e0e7ff 100%); min-height: 100vh; display: flex;">
    
    <!-- 侧边栏导航 -->
    <aside :class="sidebarCollapsed ? 'w-20' : 'w-72'" class="bg-white/90 shadow-xl transition-all duration-200 ease-out border-r border-white/20 flex flex-col" style="background: rgba(255, 255, 255, 0.95); box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); border-right: 1px solid rgba(255, 255, 255, 0.2);">
      
      <!-- 侧边栏头部 -->
      <div :class="sidebarCollapsed ? 'p-2' : 'p-4'" class="border-b border-gray-100/50">
        <div :class="sidebarCollapsed ? 'flex items-center justify-center' : 'flex items-center space-x-3'">
          <div class="bg-gradient-to-r from-blue-600 to-indigo-600 text-white rounded-xl shadow-lg flex-shrink-0" :class="sidebarCollapsed ? 'p-2' : 'p-3'" style="background: linear-gradient(135deg, #2563eb 0%, #4f46e5 100%); color: white; border-radius: 12px; box-shadow: 0 10px 25px rgba(37, 99, 235, 0.3);">
            <i class="fa-solid fa-video text-xl"></i>
          </div>
          <div v-show="!sidebarCollapsed" class="transition-opacity duration-300">
            <h1 class="text-lg font-bold bg-gradient-to-r from-blue-600 to-indigo-600 bg-clip-text text-transparent" style="font-weight: 700; background: linear-gradient(135deg, #2563eb 0%, #4f46e5 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;">智能看护系统</h1>
            <p class="text-xs text-gray-500 flex items-center">
              <span class="w-2 h-2 bg-green-400 rounded-full mr-2 animate-pulse"></span>
              监控系统
            </p>
          </div>
        </div>
      </div>
          
      <!-- 导航菜单 -->
      <nav :class="sidebarCollapsed ? 'flex-1 p-2 space-y-2' : 'flex-1 p-4 space-y-2'">
        <div class="space-y-1">
          <!-- 实时监控 -->
          <div class="relative group">
            <button 
              @click="activeTab = 'live'" 
              :class="[
                activeTab === 'live' ? 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' : 'text-gray-600 hover:text-blue-600 hover:bg-blue-50',
                sidebarCollapsed ? 'w-full flex items-center justify-center px-2 py-3 rounded-xl transition-colors duration-150' : 'w-full flex items-center space-x-3 px-4 py-3 rounded-xl transition-colors duration-150'
              ]"
              :title="sidebarCollapsed ? '实时监控' : ''">
              <div class="flex-shrink-0">
                <i class="fa-solid fa-video text-lg"></i>
              </div>
              <span v-show="!sidebarCollapsed" class="font-medium transition-opacity duration-300">实时监控</span>
            </button>
            </div>

          <!-- 录制回放 -->
          <div class="relative group">
            <button 
              @click="activeTab = 'recordings'" 
              :class="[
                activeTab === 'recordings' ? 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' : 'text-gray-600 hover:text-blue-600 hover:bg-blue-50',
                sidebarCollapsed ? 'w-full flex items-center justify-center px-2 py-3 rounded-xl transition-colors duration-150' : 'w-full flex items-center space-x-3 px-4 py-3 rounded-xl transition-colors duration-150'
              ]"
              :title="sidebarCollapsed ? '录制回放' : ''">
              <div class="flex-shrink-0">
                <i class="fa-solid fa-history text-lg"></i>
              </div>
              <span v-show="!sidebarCollapsed" class="font-medium transition-opacity duration-300">录制回放</span>
            </button>
        </div>

          <!-- 人脸管理 -->
          <div class="relative group">
            <button 
              @click="activeTab = 'face-management'" 
              :class="[
                activeTab === 'face-management' ? 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' : 'text-gray-600 hover:text-blue-600 hover:bg-blue-50',
                sidebarCollapsed ? 'w-full flex items-center justify-center px-2 py-3 rounded-xl transition-colors duration-150' : 'w-full flex items-center space-x-3 px-4 py-3 rounded-xl transition-colors duration-150'
              ]"
              :title="sidebarCollapsed ? '人脸管理' : ''">
              <div class="flex-shrink-0">
                <i class="fa-solid fa-users text-lg"></i>
        </div>
              <span v-show="!sidebarCollapsed" class="font-medium transition-opacity duration-300">人脸管理</span>
            </button>
      </div>
        
          <!-- SLAM建图 -->
          <div class="relative group">
            <button 
              @click="goToSlamManager" 
              :class="[
                'text-gray-600 hover:text-purple-600 hover:bg-purple-50',
                sidebarCollapsed ? 'w-full flex items-center justify-center px-2 py-3 rounded-xl transition-colors duration-150' : 'w-full flex items-center space-x-3 px-4 py-3 rounded-xl transition-colors duration-150'
              ]"
              :title="sidebarCollapsed ? 'SLAM建图' : ''">
              <div class="flex-shrink-0">
                <i class="fa-solid fa-map text-lg"></i>
              </div>
              <span v-show="!sidebarCollapsed" class="font-medium transition-opacity duration-300">SLAM建图</span>
            </button>
          </div>
        </div>

        <!-- 分隔线 -->
        <div class="border-t border-gray-100/50 my-4"></div>

        <!-- 系统状态 -->
        <div v-show="!sidebarCollapsed" class="space-y-2">
          <h3 class="text-xs font-semibold text-gray-500 uppercase tracking-wider">系统状态</h3>
          <div class="space-y-1">
            <div class="flex items-center space-x-2 px-3 py-2 bg-green-50 rounded-lg">
              <div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
              <span class="text-xs text-green-700">系统在线</span>
            </div>
            <div class="flex items-center space-x-2 px-3 py-2 bg-blue-50 rounded-lg">
              <div class="w-2 h-2 bg-blue-400 rounded-full"></div>
              <span class="text-xs text-blue-700">视频流正常</span>
            </div>
          </div>
        </div>
      </nav>

      <!-- 侧边栏底部 -->
      <div class="p-4 border-t border-gray-100/50">
        <!-- 用户信息 -->
        <div v-show="!sidebarCollapsed" class="flex items-center space-x-3 bg-white/50 rounded-lg px-3 py-2 backdrop-blur-sm">
          <div class="relative">
            <img :src="config.services.avatar" alt="用户头像" class="h-8 w-8 rounded-full object-cover border-2 border-blue-200 shadow-sm">
            <div class="absolute -bottom-1 -right-1 w-3 h-3 bg-green-400 border-2 border-white rounded-full"></div>
          </div>
          <div class="flex-1 min-w-0">
            <p class="text-sm font-medium text-gray-800 truncate">{{ sysUser.username || '用户' }}</p>
            <p class="text-xs text-gray-500">监控用户</p>
          </div>
          <button @click="logout" class="text-gray-400 hover:text-red-500 transition-colors">
            <i class="fa-solid fa-sign-out-alt text-sm"></i>
          </button>
        </div>
      </div>
    </aside>

    <!-- 浮动收缩按钮 - 固定在页面左下角 -->
    <button 
      @click="toggleSidebar"
      class="fixed bottom-4 left-4 z-50 bg-blue-500 hover:bg-blue-600 text-white p-3 rounded-full shadow-lg transition-colors duration-200"
      :title="sidebarCollapsed ? '展开侧边栏' : '收缩侧边栏'">
      <i :class="sidebarCollapsed ? 'fa-solid fa-chevron-right' : 'fa-solid fa-chevron-left'" class="text-lg"></i>
    </button>

    <!-- 主内容区域 -->
    <div class="flex-1 flex flex-col min-h-screen">
      <!-- 顶部状态栏 -->
      <header class="bg-white/80 backdrop-blur-md shadow-lg border-b border-white/20 flex-shrink-0" style="background: rgba(255, 255, 255, 0.8); backdrop-filter: blur(12px); box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(255, 255, 255, 0.2);">
        <div class="px-6 py-4">
          <div class="flex justify-between items-center">
            <div>
              <h1 class="text-2xl font-bold bg-gradient-to-r from-gray-800 to-gray-600 bg-clip-text text-transparent">实时视频监控</h1>
              <p class="text-gray-600 flex items-center mt-1">
                <i class="fa-solid fa-eye mr-2 text-blue-500"></i>
                监控看护车运行状态和实时视频流
              </p>
            </div>
            <div class="flex items-center space-x-4">
              <div class="text-right">
                <p class="text-sm text-gray-500">当前时间</p>
                <p class="text-lg font-mono text-gray-800">{{ currentTime }}</p>
              </div>
            </div>
          </div>
        </div>
      </header>

    <!-- 主内容区域 -->
    <main class="flex-1 overflow-y-auto p-4 md:p-6 lg:p-8">

      <!-- 实时监控区域 -->
      <div v-if="activeTab === 'live'" class="bg-white/80 backdrop-blur-sm rounded-2xl overflow-hidden shadow-2xl border border-white/20 mb-8" style="background: rgba(255, 255, 255, 0.8); backdrop-filter: blur(8px); border-radius: 16px; overflow: hidden; box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15); border: 1px solid rgba(255, 255, 255, 0.2); margin-bottom: 2rem;">
            <div class="p-6 border-b border-gray-100/50 flex justify-between items-center bg-gradient-to-r from-white/50 to-blue-50/50">
              <div class="flex items-center space-x-3">
                <div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
                <h2 class="font-semibold text-xl text-gray-800">实时视频监控</h2>
              </div>
              <div class="flex space-x-3">
                <!-- 人脸识别开关 -->
                <button @click="toggleFaceRecognition" 
                        :class="faceRecognitionEnabled ? 'bg-gradient-to-r from-green-500 to-green-600 text-white' : 'bg-gradient-to-r from-gray-100 to-gray-200 text-gray-700'"
                        class="px-4 py-2 text-sm rounded-lg hover:shadow-lg transition-all duration-200 shadow-md transform hover:-translate-y-0.5">
                  <i :class="faceRecognitionEnabled ? 'fa-solid fa-eye' : 'fa-solid fa-eye-slash'" class="mr-2"></i>
                  {{ faceRecognitionEnabled ? '人脸识别已启用' : '启用人脸识别' }}
                </button>
                <!-- YOLO目标检测开关 -->
                <button @click="toggleYOLODetection" 
                        :class="yoloDetectionEnabled ? 'bg-gradient-to-r from-purple-500 to-purple-600 text-white' : 'bg-gradient-to-r from-gray-100 to-gray-200 text-gray-700'"
                        class="px-4 py-2 text-sm rounded-lg hover:shadow-lg transition-all duration-200 shadow-md transform hover:-translate-y-0.5">
                  <i :class="yoloDetectionEnabled ? 'fa-solid fa-crosshairs' : 'fa-solid fa-crosshairs'" class="mr-2"></i>
                  {{ yoloDetectionEnabled ? 'YOLO检测已启用' : '启用YOLO检测' }}
                </button>
                
                <!-- YOLO置信度阈值控制 -->
                <div v-if="yoloDetectionEnabled" class="flex items-center space-x-2 bg-white/80 backdrop-blur-sm rounded-lg px-3 py-2 shadow-md">
                  <i class="fa-solid fa-filter text-purple-600 text-xs"></i>
                  <span class="text-xs text-gray-600">阈值:</span>
                  <input 
                    type="range" 
                    min="0.1" 
                    max="0.9" 
                    step="0.05" 
                    v-model="yoloConfidenceThreshold"
                    class="w-16 h-2 bg-purple-200 rounded-lg appearance-none cursor-pointer slider"
                    :style="`background: linear-gradient(to right, #e5e7eb 0%, #e5e7eb ${((yoloConfidenceThreshold - 0.1) / (0.9 - 0.1)) * 100}%, #8b5cf6 ${((yoloConfidenceThreshold - 0.1) / (0.9 - 0.1)) * 100}%, #8b5cf6 100%);`"
                  />
                  <span class="text-xs text-purple-600 font-medium min-w-[3rem]">
                    {{ Math.round(yoloConfidenceThreshold * 100) }}%
                  </span>
                </div>
                <button @click="toggleFullscreen" class="px-4 py-2 text-sm bg-gradient-to-r from-gray-100 to-gray-200 text-gray-700 rounded-lg hover:from-gray-200 hover:to-gray-300 transition-all duration-200 shadow-md hover:shadow-lg transform hover:-translate-y-0.5">
                  <i :class="isFullscreen ? 'fa-solid fa-compress' : 'fa-solid fa-expand'" class="mr-2"></i> 
                  {{ isFullscreen ? '退出全屏' : '全屏' }}
                </button>
              </div>
            </div>
            
            <!-- 视频和用户信息区域 -->
            <div class="flex gap-6">
              <!-- 视频区域 -->
              <div class="flex-1">
                <div class="relative video-container" :class="{ 'fullscreen-mode': isFullscreen }">
              <!-- 主视频流 -->
              <div class="aspect-video bg-gradient-to-br from-gray-900 via-gray-800 to-black relative overflow-hidden cursor-pointer" style="aspect-ratio: 16/9; background: linear-gradient(135deg, #111827 0%, #1f2937 50%, #000000 100%); position: relative; overflow: hidden; border-radius: 8px;" @click="handleVideoClick" @mousemove="handleVideoMouseMove">
                <video ref="mainVideo" autoplay :muted="isMuted" playsinline class="w-full h-full object-cover" @loadstart="isLoading = true" @canplay="handleVideoCanPlay" @error="handleVideoError">
                  您的浏览器不支持WebRTC视频播放
                </video>
                <!-- 连接状态指示器 - 全屏模式下仅在未连接时显示 -->
                <div v-if="!isFullscreen || connectionStatus !== '已连接'" class="absolute top-4 left-4 text-white text-sm px-3 py-2 rounded-lg flex items-center backdrop-blur-sm shadow-lg" 
                     :class="connectionStatus === '已连接' ? 'bg-gradient-to-r from-green-500/90 to-green-600/90' : 
                             connectionStatus === '连接失败' ? 'bg-gradient-to-r from-red-500/90 to-red-600/90' : 
                             'bg-gradient-to-r from-yellow-500/90 to-yellow-600/90'">
                  <span class="w-2 h-2 rounded-full mr-2" 
                        :class="connectionStatus === '已连接' ? 'bg-white' : 
                                connectionStatus === '连接失败' ? 'bg-white' : 
                                'bg-white animate-pulse'"></span> {{ connectionStatus }}
                </div>
                <!-- 设备ID - 全屏模式下仅在未连接时显示 -->
                <div v-if="!isFullscreen || connectionStatus !== '已连接'" class="absolute bottom-4 left-4 bg-black/70 text-white text-sm px-3 py-2 rounded-lg backdrop-blur-sm shadow-lg">
                  <i class="fa-solid fa-microchip mr-2 text-blue-400"></i>设备ID: {{ currentDevice.id }}
                </div>
                <!-- 信号信息 - 全屏模式下仅在未连接时显示 -->
                <div v-if="!isFullscreen || connectionStatus !== '已连接'" class="absolute bottom-4 right-4 bg-black/70 text-white text-sm px-3 py-2 rounded-lg backdrop-blur-sm shadow-lg">
                  <i class="fa-solid fa-signal mr-2 text-green-400"></i> {{ signalInfo }}
                </div>
                <!-- 加载状态 -->
                <div v-if="isLoading" class="absolute inset-0 bg-gradient-to-br from-gray-900 via-gray-800 to-black flex items-center justify-center" :class="{ 'loading-fullscreen': isFullscreen }">
                  <div class="text-center text-white">
                    <div v-if="!isFullscreen" class="relative loading-spinner">
                      <i class="fa-solid fa-spinner fa-spin text-4xl mb-4 text-blue-400"></i>
                      <div class="absolute inset-0 rounded-full border-2 border-blue-400/30 border-t-blue-400 animate-spin"></div>
                    </div>
                    <p class="text-lg font-medium">正在连接视频流...</p>
                    <p class="text-sm text-gray-400 mt-2">请稍候，正在建立连接</p>
                  </div>
                </div>
                <!-- 错误状态 -->
                <div v-if="hasError" class="absolute inset-0 bg-gradient-to-br from-gray-900 via-gray-800 to-black flex items-center justify-center">
                  <div class="text-center text-white max-w-md mx-auto px-4">
                    <div class="bg-yellow-500/20 rounded-full p-4 mb-4">
                      <i class="fa-solid fa-exclamation-triangle text-4xl text-yellow-400"></i>
                    </div>
                    <p class="text-lg font-medium mb-2">连接异常</p>
                    <p class="text-sm text-gray-400 mb-4 whitespace-pre-line">{{ errorMessage }}</p>
                    <button @click="autoConnectVideoStream" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg transition-colors">
                      <i class="fa-solid fa-refresh mr-2"></i>重新连接
                    </button>
                  </div>
                </div>
                
                <!-- 人脸识别覆盖层 -->
                <div v-if="faceRecognitionEnabled && detectedFaces.length > 0" class="absolute inset-0 pointer-events-none">
                  <div v-for="(face, index) in detectedFaces" :key="index" 
                       class="absolute border-2 rounded-lg shadow-lg"
                       :class="face.recognized ? 'border-green-400 bg-green-400/20' : 'border-yellow-400 bg-yellow-400/20'"
                       :style="{
                         left: face.x + 'px',
                         top: face.y + 'px',
                         width: face.width + 'px',
                         height: face.height + 'px'
                       }">
                    <!-- 人脸标签 -->
                    <div class="absolute -top-6 left-0 bg-black/70 text-white text-xs px-2 py-1 rounded">
                      {{ face.recognizedName || 'Unknown' }}
                      <span v-if="face.confidence" class="ml-1 text-yellow-300">
                        {{ Math.round(face.confidence) }}%
                      </span>
                    </div>
                  </div>
                </div>
                
                <!-- YOLO目标检测结果 -->
                <div v-if="yoloDetectionEnabled" v-for="(object, index) in detectedObjects" :key="'yolo-' + index">
                  <div 
                       class="absolute border-2 rounded-lg shadow-lg"
                       :class="'border-red-400 bg-red-400/20'"
                       :style="{
                         left: object.x + 'px',
                         top: object.y + 'px',
                         width: object.width + 'px',
                         height: object.height + 'px'
                       }">
                    <!-- 目标标签 -->
                    <div class="absolute -top-6 left-0 bg-red-600/80 text-white text-xs px-2 py-1 rounded">
                      {{ object.class || 'Object' }}
                      <span v-if="object.confidence" class="ml-1 text-yellow-300">
                        {{ Math.round(object.confidence) }}%
                      </span>
                    </div>
                  </div>
                </div>
                
                <!-- 全屏提示 -->
                <div v-if="!isFullscreen && !isLoading" class="absolute top-4 right-4 bg-black/70 text-white text-xs px-3 py-2 rounded-lg backdrop-blur-sm opacity-0 hover:opacity-100 transition-opacity duration-300">
                  <div class="flex items-center space-x-2">
                    <i class="fa-solid fa-keyboard"></i>
                    <span>按 F 键全屏，ESC 退出</span>
                  </div>
                </div>
                
                <!-- 全屏模式下的快捷键提示 - 仅在未连接时显示 -->
                <div v-if="isFullscreen && connectionStatus !== '已连接'" class="absolute bottom-24 right-2 bg-black/90 text-white text-xs px-2 py-1 rounded-lg backdrop-blur-sm z-50 border border-white/20">
                  <div class="flex items-center space-x-1">
                    <i class="fa-solid fa-keyboard text-xs"></i>
                    <span class="text-xs">ESC</span>
                  </div>
                </div>
                
                <!-- 全屏模式提示 - 仅在未连接时显示 -->
                <div v-if="isFullscreen && showFullscreenTip && connectionStatus !== '已连接'" class="absolute top-24 right-2 bg-black/90 text-white text-xs px-2 py-1 rounded-lg backdrop-blur-sm z-50 border border-white/20 animate-fade-in">
                  <div class="text-center">
                    <div class="flex items-center justify-center space-x-1 mb-1">
                      <i class="fa-solid fa-expand text-blue-400 text-xs"></i>
                      <span class="font-semibold text-xs">全屏</span>
                    </div>
                    <p class="text-xs text-gray-300">ESC退出</p>
                  </div>
                </div>
                
                <!-- 全屏模式下的控制栏切换按钮 -->
                <div v-if="isFullscreen" class="absolute top-4 right-4 flex space-x-2" style="z-index: 1000000;">
                  <button @click.stop="toggleControls" class="bg-black/50 hover:bg-black/70 text-white text-xs px-3 py-2 rounded backdrop-blur-sm transition-all duration-300 cursor-pointer" :title="showControls ? '隐藏控制栏' : '显示控制栏'">
                    <i :class="showControls ? 'fa-solid fa-eye-slash' : 'fa-solid fa-eye'" class="mr-1"></i>
                    {{ showControls ? '隐藏' : '显示' }}
                  </button>
                  <button @click.stop="toggleFullscreen" class="bg-black/50 hover:bg-black/70 text-white text-xs px-3 py-2 rounded backdrop-blur-sm transition-all duration-300 cursor-pointer" title="退出全屏">
                    <i class="fa-solid fa-compress mr-1"></i>
                    ESC
                  </button>
                </div>
                
                <!-- 工作线程状态显示 -->
                <div v-if="isFullscreen" class="absolute top-4 left-4 bg-blue-500/80 text-white text-xs px-2 py-1 rounded" style="z-index: 1000000;">
                  <div>视频监控: {{ isVideoMonitoringActive ? '运行中' : '已停止' }}</div>
                  <div>录制回放: {{ isRecordingPlaybackActive ? '运行中' : '已停止' }}</div>
              </div>
              
                
                <!-- 独立的全屏控制栏 -->
                <div v-if="isFullscreen && showControls" class="fixed bottom-0 left-0 right-0 bg-black/50 backdrop-blur-sm p-4 flex justify-between items-center" style="height: 80px; min-height: 80px; z-index: 999999;">
                  <div class="flex items-center space-x-6">
                    <button @click="togglePlayPause" class="p-3 rounded-xl bg-blue-600 text-white hover:bg-blue-700 transition-all duration-200" title="播放/暂停">
                      <i :class="isPlaying ? 'fa-solid fa-pause text-xl' : 'fa-solid fa-play text-xl'"></i>
                    </button>
                    <div class="flex items-center space-x-2 bg-white/20 rounded-lg px-3 py-2">
                      <i class="fa-solid fa-clock text-blue-400"></i>
                      <span class="text-sm font-medium text-white">{{ currentTime }}</span>
                    </div>
                  </div>
                  <div class="flex items-center space-x-4">
                    <!-- 音量控制区域 - 移到最右边并半透明 -->
                    <div class="relative volume-control-container">
                      <button @click="toggleVolumeControl" class="p-3 rounded-xl bg-gray-600/80 backdrop-blur-sm text-white hover:bg-gray-700/80 transition-all duration-200" title="音量控制">
                        <i :class="isMuted || volume === 0 ? 'fa-solid fa-volume-mute text-lg' : 'fa-solid fa-volume-up text-lg'"></i>
                      </button>
                      
                      <!-- 音量调节弹出层 - 半透明竖直调节 -->
                      <div v-if="showVolumeControl" class="absolute bottom-full right-0 mb-2 bg-white/80 backdrop-blur-sm rounded-lg shadow-lg border border-gray-200/50 p-4 z-50">
                        <div class="flex flex-col items-center space-y-3">
                          <div class="text-sm font-medium text-gray-700">音量调节</div>
                          <div class="flex flex-col items-center space-y-3">
                            <i class="fa-solid fa-volume-up text-gray-500"></i>
                            <input 
                              type="range" 
                              min="0" 
                              max="100" 
                              v-model="volume" 
                              @input="updateVolume"
                              class="w-2 h-32 bg-gray-300/80 rounded-lg appearance-none cursor-pointer slider-vertical"
                              title="音量控制"
                              style="writing-mode: bt-lr; -webkit-appearance: slider-vertical; appearance: slider-vertical;"
                            />
                            <i class="fa-solid fa-volume-down text-gray-500"></i>
                          </div>
                          <div class="text-xs text-gray-600 font-medium">{{ volume }}%</div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              
              <!-- 视频控制栏 -->
              <div class="video-controls bg-gradient-to-r from-white/90 to-blue-50/90 backdrop-blur-sm p-6 flex justify-between items-center border-t border-gray-100/50 transition-opacity duration-300" 
                   :class="{ 'opacity-0': isFullscreen && !showControls, 'opacity-100': !isFullscreen || showControls }"
                   :style="isFullscreen ? 'position: fixed !important; bottom: 0 !important; left: 0 !important; right: 0 !important; z-index: 999999 !important; background: rgba(0, 0, 0, 0.95) !important; backdrop-filter: blur(10px) !important; width: 100vw !important; height: 80px !important; display: flex !important; min-height: 80px !important;' : ''"
                   v-show="!isFullscreen || showControls">
                <div class="flex items-center space-x-6">
                  <button @click="togglePlayPause" class="p-4 rounded-xl bg-gradient-to-r from-blue-500 to-blue-600 text-white hover:from-blue-600 hover:to-blue-700 transition-all duration-200 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5" title="播放/暂停">
                    <i :class="isPlaying ? 'fa-solid fa-pause text-xl' : 'fa-solid fa-play text-xl'"></i>
                  </button>
                  <div class="flex items-center space-x-2 bg-white/50 rounded-lg px-3 py-2">
                    <i class="fa-solid fa-clock text-blue-500"></i>
                    <span class="text-sm font-medium text-gray-700">{{ currentTime }}</span>
                  </div>
                </div>
                <div class="flex items-center space-x-4">
                  <!-- 音量控制区域 -->
                  <div class="relative volume-control-container">
                    <button @click="toggleVolumeControl" class="p-3 rounded-xl bg-gradient-to-r from-gray-100 to-gray-200 text-gray-600 hover:from-gray-200 hover:to-gray-300 transition-all duration-200 shadow-md hover:shadow-lg transform hover:-translate-y-0.5" title="音量控制">
                      <i :class="isMuted || volume === 0 ? 'fa-solid fa-volume-mute text-lg' : 'fa-solid fa-volume-up text-lg'"></i>
                  </button>
                    
                    <!-- 音量调节弹出层 -->
                    <div v-if="showVolumeControl" class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 bg-white/90 backdrop-blur-sm rounded-lg shadow-lg border border-gray-200/50 p-4 z-50">
                      <div class="flex flex-col items-center space-y-3">
                        <div class="text-sm font-medium text-gray-700">音量调节</div>
                        <div class="flex items-center space-x-3">
                          <i class="fa-solid fa-volume-down text-gray-500"></i>
                          <input 
                            type="range" 
                            min="0" 
                            max="100" 
                            v-model="volume" 
                            @input="updateVolume"
                            class="w-32 h-2 bg-gray-300 rounded-lg appearance-none cursor-pointer slider"
                            title="音量控制"
                          />
                          <i class="fa-solid fa-volume-up text-gray-500"></i>
                        </div>
                        <div class="text-xs text-gray-600 font-medium">{{ volume }}%</div>
                      </div>
                    </div>
                  </div>
                  
                  <button @click="refreshVideoStream" class="p-3 rounded-xl bg-gradient-to-r from-green-100 to-green-200 text-green-600 hover:from-green-200 hover:to-green-300 transition-all duration-200 shadow-md hover:shadow-lg transform hover:-translate-y-0.5" title="刷新视频流">
                    <i class="fa-solid fa-sync-alt text-lg"></i>
                  </button>
                </div>
              </div>
              
                </div>
              </div>
              
              <!-- 右侧用户信息面板 -->
            <div class="w-80 bg-white/90 backdrop-blur-sm rounded-2xl shadow-xl border border-white/20 overflow-hidden" style="background: rgba(255, 255, 255, 0.9); backdrop-filter: blur(8px); border-radius: 16px; box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15); border: 1px solid rgba(255, 255, 255, 0.2);">
              <!-- 面板标题 -->
              <div class="p-4 border-b border-gray-200/50 bg-gradient-to-r from-blue-50/50 to-indigo-50/50">
                <div class="flex items-center space-x-3">
                  <div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
                  <h3 class="font-semibold text-lg text-gray-800">识别用户</h3>
                  <span class="text-sm text-gray-500">实时检测</span>
                </div>
              </div>
              
              <!-- 用户列表 -->
              <div class="p-4 max-h-96 overflow-y-auto">
                <!-- 当前检测到的用户 -->
                <div v-if="detectedFaces.length > 0" class="space-y-3">
                  <div 
                    v-for="(face, index) in detectedFaces" 
                    :key="'user-' + index"
                    class="flex items-center space-x-3 p-3 bg-gradient-to-r from-green-50 to-emerald-50 rounded-xl border border-green-200/50 hover:shadow-md transition-all duration-200">
                    <!-- 用户头像 -->
                    <div class="relative">
                      <div class="w-12 h-12 bg-gradient-to-br from-green-400 to-emerald-500 rounded-full flex items-center justify-center text-white font-bold text-lg shadow-lg">
                        {{ (face.recognizedName || 'Unknown').charAt(0) }}
                      </div>
                      <div class="absolute -bottom-1 -right-1 w-4 h-4 bg-green-400 border-2 border-white rounded-full"></div>
                    </div>
                    
                    <!-- 用户信息 -->
                    <div class="flex-1 min-w-0">
                      <div class="flex items-center space-x-2">
                        <h4 class="font-semibold text-gray-800 truncate">
                          {{ face.recognizedName || 'Unknown' }}
                        </h4>
                        <span v-if="face.confidence" class="text-xs px-2 py-1 bg-green-100 text-green-700 rounded-full font-medium">
                          {{ Math.round(face.confidence) }}%
                        </span>
                      </div>
                      <p class="text-sm text-gray-600">
                        {{ face.recognized ? '已识别' : '检测中...' }}
                      </p>
                      <p class="text-xs text-gray-500">
                        {{ formatTime(new Date(face.timestamp)) }}
                      </p>
                    </div>
                    
                    <!-- 状态图标 -->
                    <div class="flex-shrink-0">
                      <i v-if="face.recognized" class="fa-solid fa-check-circle text-green-500 text-lg"></i>
                      <i v-else class="fa-solid fa-question-circle text-yellow-500 text-lg"></i>
                    </div>
                  </div>
                </div>
                
                <!-- 无人脸检测时的状态 -->
                <div v-else-if="faceRecognitionEnabled" class="text-center py-8">
                  <div class="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
                    <i class="fa-solid fa-user-slash text-2xl text-gray-400"></i>
                  </div>
                  <p class="text-gray-600 font-medium">未检测到人脸</p>
                  <p class="text-sm text-gray-500 mt-1">请确保人脸在摄像头范围内</p>
                </div>
                
                <!-- 人脸识别未启用时的状态 -->
                <div v-else class="text-center py-8">
                  <div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">
                    <i class="fa-solid fa-eye-slash text-2xl text-blue-400"></i>
                  </div>
                  <p class="text-gray-600 font-medium">人脸识别未启用</p>
                  <p class="text-sm text-gray-500 mt-1">点击上方按钮启用人脸识别</p>
                </div>
              </div>
              
              <!-- 面板底部统计 -->
              <div class="p-4 border-t border-gray-200/50 bg-gradient-to-r from-gray-50/50 to-blue-50/50">
                <div class="flex items-center justify-between text-sm">
                  <div class="flex items-center space-x-2">
                    <i class="fa-solid fa-users text-gray-500"></i>
                    <span class="text-gray-600">检测到 {{ detectedFaces.length }} 人</span>
                  </div>
                  <div class="flex items-center space-x-2">
                    <i class="fa-solid fa-clock text-gray-500"></i>
                    <span class="text-gray-600">{{ formatTime(new Date()) }}</span>
                  </div>
                </div>
              </div>
            </div>
            </div>
      </div>


      <!-- 监控回放区域 -->
      <div v-if="activeTab === 'recordings'" class="bg-white/80 backdrop-blur-sm rounded-2xl overflow-hidden shadow-2xl border border-white/20 mb-8" style="background: rgba(255, 255, 255, 0.8); backdrop-filter: blur(8px); border-radius: 16px; overflow: hidden; box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15); border: 1px solid rgba(255, 255, 255, 0.2); margin-bottom: 2rem;">
        <div class="p-6 border-b border-gray-100/50 flex justify-between items-center bg-gradient-to-r from-white/50 to-blue-50/50">
          <div class="flex items-center space-x-3">
            <div class="w-2 h-2 bg-blue-400 rounded-full animate-pulse"></div>
            <h2 class="font-semibold text-xl text-gray-800">监控回放</h2>
            <span class="text-sm text-gray-500">历史录像查看</span>
          </div>
        </div>
        
        <!-- 日期选择区域 -->
        <div class="p-6 border-b border-gray-100/50 bg-gradient-to-r from-gray-50/50 to-blue-50/50">
          <div class="flex items-center justify-center space-x-6">
            <!-- 日期选择器 -->
            <div class="flex items-center space-x-4">
              <label class="text-sm font-medium text-gray-700">选择日期：</label>
              <input 
                v-model="selectedDate" 
                type="date" 
                :max="todayDate"
                @change="onDateChange"
                class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-center">
              <button 
                @click="goToToday" 
                class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors duration-200">
                <i class="fa-solid fa-calendar-day mr-1"></i> 今天
                  </button>
            </div>
            
            <!-- 日期导航 -->
            <div class="flex items-center space-x-2">
              <button @click="goToPreviousDay" class="p-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition-colors duration-200">
                <i class="fa-solid fa-chevron-left"></i>
              </button>
              <span class="px-4 py-2 bg-white border border-gray-300 rounded-lg text-sm font-medium">
                {{ formatSelectedDate }}
              </span>
              <button 
                @click="goToNextDay" 
                :disabled="isNextDayDisabled"
                class="p-2 rounded-lg transition-colors duration-200"
                :class="isNextDayDisabled ? 'bg-gray-100 text-gray-400 cursor-not-allowed' : 'bg-gray-200 text-gray-700 hover:bg-gray-300'">
                <i class="fa-solid fa-chevron-right"></i>
                  </button>
            </div>
                </div>
              </div>
              
        
        
        <!-- 录像查看区域 -->
        <div class="p-6">
          <div v-if="isLoadingRecordings" class="text-center py-8">
            <i class="fa-solid fa-spinner fa-spin text-4xl text-blue-500 mb-4"></i>
            <p class="text-gray-600">加载监控录像...</p>
          </div>
          
          <div v-else-if="recordings.length === 0" class="text-center py-8">
            <i class="fa-solid fa-video-slash text-6xl text-gray-300 mb-4"></i>
            <p class="text-gray-600 text-lg">暂无监控录像</p>
            <p class="text-gray-500 text-sm">请选择其他日期查看历史录像</p>
          </div>
          
          <div v-else>
            <!-- 录像概览 -->
            <div class="mb-6">
              <h3 class="text-lg font-semibold text-gray-800 mb-4 flex items-center">
                <i class="fa-solid fa-video mr-2 text-blue-500"></i>
                {{ formatSelectedDate }} 的监控录像
                <span class="ml-2 text-sm font-normal text-gray-500">(共 {{ recordings.length }} 个)</span>
              </h3>
            </div>
            
            <!-- 录像列表 -->
            <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
              <div 
                v-for="recording in recordings" 
                :key="recording.id"
                class="surveillance-card">
              <!-- 视频缩略图 -->
              <div class="recording-thumbnail relative aspect-video rounded-t-xl overflow-hidden">
                <img 
                  v-if="recording.thumbnailPath" 
                  :src="recording.thumbnailPath" 
                  :alt="recording.streamName"
                  class="w-full h-full object-cover">
                <div v-else class="w-full h-full flex items-center justify-center">
                  <i class="fa-solid fa-video text-4xl text-gray-400"></i>
                </div>
                <!-- 状态标签 -->
                <div class="absolute top-2 left-2">
                  <span 
                    :class="getStatusClass(recording.status)"
                    class="px-2 py-1 text-xs font-medium rounded-full">
                    {{ getStatusText(recording.status) }}
                  </span>
                </div>
                <!-- 时长标签 -->
                <div v-if="recording.duration" class="absolute bottom-2 right-2 bg-black/70 text-white text-xs px-2 py-1 rounded">
                  {{ formatDuration(recording.duration) }}
                </div>
                <!-- 播放按钮 -->
                <div class="play-overlay">
                  <button 
                    @click="playRecording(recording)"
                    class="play-button">
                    <i class="fa-solid fa-play ml-1"></i>
                  </button>
                </div>
              </div>
              
              <!-- 视频信息 -->
              <div class="p-4">
                <h3 class="font-semibold text-gray-800 mb-2">{{ recording.streamName }}</h3>
                <div class="space-y-1 text-sm text-gray-600">
                  <div class="flex items-center">
                    <i class="fa-solid fa-calendar mr-2"></i>
                    {{ formatDateTime(recording.startTime) }}
                  </div>
                  <div v-if="recording.endTime" class="flex items-center">
                    <i class="fa-solid fa-calendar-check mr-2"></i>
                    {{ formatDateTime(recording.endTime) }}
                  </div>
                  <div v-if="recording.fileSize" class="flex items-center">
                    <i class="fa-solid fa-file mr-2"></i>
                    {{ formatFileSize(recording.fileSize) }}
                  </div>
                  <div v-if="recording.filePath" class="flex items-center">
                    <i class="fa-solid fa-file-video mr-2"></i>
                    {{ getFileFormatDisplay(recording.filePath) }}
                  </div>
                  <div v-if="recording.duration" class="flex items-center">
                    <i class="fa-solid fa-clock mr-2"></i>
                    {{ formatDuration(recording.duration) }}
                  </div>
                </div>
                
                <!-- 操作按钮 -->
                <div class="mt-4 flex space-x-2">
                  <button 
                    @click="playRecording(recording)"
                    class="flex-1 px-3 py-2 bg-blue-500 text-white text-sm rounded-lg hover:bg-blue-600 transition-colors duration-200">
                    <i class="fa-solid fa-play mr-1"></i> 播放
                  </button>
                  <button 
                    @click="downloadRecording(recording)"
                    class="px-3 py-2 bg-green-500 text-white text-sm rounded-lg hover:bg-green-600 transition-colors duration-200">
                    <i class="fa-solid fa-download"></i>
                  </button>
                </div>
              </div>
              </div>
            </div>
            
            <!-- 分页 -->
            <div v-if="recordings.length > 0" class="mt-6 flex justify-center">
              <div class="flex space-x-2">
                <button 
                  @click="prevPage" 
                  :disabled="currentPage <= 1"
                  class="px-4 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200">
                  <i class="fa-solid fa-chevron-left mr-1"></i> 上一页
                </button>
                <span class="px-4 py-2 bg-blue-500 text-white rounded-lg">
                  {{ currentPage }} / {{ totalPages }}
                </span>
                <button 
                  @click="nextPage" 
                  :disabled="currentPage >= totalPages"
                  class="px-4 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200">
                  下一页 <i class="fa-solid fa-chevron-right ml-1"></i>
                </button>
              </div>
            </div>
          </div>
            </div>
      </div>

      <!-- 人脸管理区域 -->
      <div v-if="activeTab === 'face-management'" class="bg-white/80 backdrop-blur-sm rounded-2xl overflow-hidden shadow-2xl border border-white/20 mb-8" style="background: rgba(255, 255, 255, 0.8); backdrop-filter: blur(8px); border-radius: 16px; overflow: hidden; box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15); border: 1px solid rgba(255, 255, 255, 0.2); margin-bottom: 2rem;">
        <div class="p-6 border-b border-gray-100/50 flex justify-between items-center bg-gradient-to-r from-white/50 to-blue-50/50">
          <div class="flex items-center space-x-3">
            <div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
            <h2 class="font-semibold text-xl text-gray-800">人脸识别管理</h2>
            <span class="text-sm text-gray-500">管理已注册的人脸数据</span>
          </div>
        </div>
        
        <!-- 人脸管理内容 -->
        <div class="p-6">
          <FaceRecognitionManager />
        </div>
      </div>

    </main>

    <!-- 页脚 -->
    <footer class="bg-white/80 backdrop-blur-md border-t border-white/20 py-6">
      <div class="container mx-auto px-4 sm:px-6 lg:px-8">
        <div class="text-center">
          <div class="flex items-center justify-center space-x-2 mb-2">
            <div class="w-2 h-2 bg-gradient-to-r from-blue-500 to-indigo-500 rounded-full"></div>
            <p class="text-sm text-gray-600 font-medium">© 2025 智能看护系统</p>
            <div class="w-2 h-2 bg-gradient-to-r from-indigo-500 to-purple-500 rounded-full"></div>
          </div>
          <p class="text-xs text-gray-500">保留所有权利 · 专业监控解决方案</p>
        </div>
      </div>
    </footer>
    
    <!-- 视频播放器 -->
    <VideoPlayer 
      :show="showVideoPlayer"
      :video-url="currentVideoUrl"
      :video-info="currentVideoInfo"
      @close="showVideoPlayer = false"
    />
    </div>
  </div>
</template>

<script setup>
/**
 * ShowSchedule.vue - 智能看护系统主界面组件
 * 
 * 功能特性：
 * - 实时视频监控（WebRTC/FLV/HLS）
 * - 录制回放功能
 * - 人脸识别管理
 * - YOLO目标检测
 * - SLAM建图管理
 * - 响应式设计
 * 
 * 技术栈：
 * - Vue 3 Composition API
 * - WebRTC 实时通信
 * - Tailwind CSS 样式
 * - Font Awesome 图标
 * 
 * @author 智能看护系统开发团队
 * @version 1.0.0
 * @since 2024
 */

import { ref, reactive, onMounted, onUnmounted, watch, computed } from 'vue'
import { useRouter } from 'vue-router'
import { defineUser } from '../store/userStore.js'
import VideoPlayer from './VideoPlayer.vue'
import FaceRecognitionManager from './FaceRecognitionManager.vue'
import yoloApiClient from '../utils/yoloApiClient.js'
import config, { buildUrls } from '../config/index.js'
import { getApiUrl } from '../config/faceRecognitionConfig.js'
import { safePlayVideo, setVideoStreamAndPlay } from '../utils/videoPlayManager.js'

const router = useRouter()
const sysUser = defineUser()

// 响应式数据
const currentTime = ref('')
const isPlaying = ref(false)
const isMuted = ref(false)
const volume = ref(100)
const showVolumeControl = ref(false)
const isLoading = ref(false)
const hasError = ref(false)
const errorMessage = ref('')
const connectionStatus = ref('连接中...')
const signalInfo = ref('4G (95%)')
const isFullscreen = ref(false)
const showFullscreenTip = ref(false)
const showControls = ref(false)
const controlsTimer = ref(null)
const userManuallyHidden = ref(false) // 用户手动隐藏标志
const webrtcConnection = ref(null)
const mainVideo = ref(null)

// 人脸识别相关数据
const faceRecognitionEnabled = ref(false) // 启用人脸识别
const detectedFaces = ref([])
const currentDetectionInterval = ref(2500) // 当前检测间隔（毫秒），默认2.5秒
const faceDetectionInterval = ref(null)

// 人脸管理模拟数据
const faceDatabase = ref([
  {
    id: 1,
    name: '张三',
    employeeId: 'EMP001',
    department: '护理部',
    position: '护士长',
    photo: '/api/faces/face_001.jpg',
    registeredDate: '2025-01-10 09:30:00',
    lastSeen: '2025-01-16 14:25:33',
    recognitionCount: 156,
    status: 'active',
    permissions: ['patient_access', 'medication_access']
  },
  {
    id: 2,
    name: '李四',
    employeeId: 'EMP002',
    department: '医疗部',
    position: '主治医师',
    photo: '/api/faces/face_002.jpg',
    registeredDate: '2025-01-08 14:20:00',
    lastSeen: '2025-01-16 11:45:12',
    recognitionCount: 89,
    status: 'active',
    permissions: ['patient_access', 'medical_records', 'prescription_access']
  },
  {
    id: 3,
    name: '王五',
    employeeId: 'EMP003',
    department: '行政部',
    position: '行政助理',
    photo: '/api/faces/face_003.jpg',
    registeredDate: '2025-01-12 10:15:00',
    lastSeen: '2025-01-16 08:30:45',
    recognitionCount: 67,
    status: 'active',
    permissions: ['office_access', 'document_access']
  },
  {
    id: 4,
    name: '赵六',
    employeeId: 'EMP004',
    department: '护理部',
    position: '护士',
    photo: '/api/faces/face_004.jpg',
    registeredDate: '2025-01-14 16:45:00',
    lastSeen: '2025-01-15 18:20:30',
    recognitionCount: 34,
    status: 'inactive',
    permissions: ['patient_access']
  },
  {
    id: 5,
    name: '孙七',
    employeeId: 'EMP005',
    department: '安保部',
    position: '保安队长',
    photo: '/api/faces/face_005.jpg',
    registeredDate: '2025-01-09 11:30:00',
    lastSeen: '2025-01-16 13:15:22',
    recognitionCount: 123,
    status: 'active',
    permissions: ['security_access', 'emergency_access']
  }
])

// 人脸识别统计
const faceRecognitionStats = ref({
  totalRegistered: 5,
  activeToday: 4,
  recognitionAccuracy: 98.5,
  averageRecognitionTime: 0.8
})

// YOLO目标检测相关数据
const yoloDetectionEnabled = ref(true) // 默认启用YOLO检测
const detectedObjects = ref([])
const yoloDetectionInterval = ref(null)
const lastYoloDetectionTime = ref(0) // 上次YOLO检测时间
const yoloDetectionFrequency = ref(1000) // YOLO检测频率(毫秒)
const yoloConfidenceThreshold = ref(0.4) // YOLO置信度阈值(0-1)

// 异步线程管理
const videoMonitoringWorker = ref(null) // 视频监控工作线程
const recordingPlaybackWorker = ref(null) // 录制回放工作线程
const isVideoMonitoringActive = ref(false) // 视频监控是否激活
const isRecordingPlaybackActive = ref(false) // 录制回放是否激活
const videoStreamKeepAlive = ref(null) // 视频流保持机制

// 侧边栏相关数据
const sidebarCollapsed = ref(false)

// 录制相关数据
// 定义props来接收路由参数
const props = defineProps({
  defaultTab: {
    type: String,
    default: 'live'
  }
})

const activeTab = ref(props.defaultTab)
const recordings = ref([
  {
    id: 1,
    filename: 'recording_20250116_143022.mp4',
    streamName: 'main_stream',
    startTime: '2025-01-16 14:30:22',
    endTime: '2025-01-16 15:45:18',
    duration: '1小时14分56秒',
    fileSize: '2.3GB',
    status: 'completed',
    thumbnail: '/api/recordings/thumbnails/recording_20250116_143022.jpg',
    description: '智能看护系统日常巡逻录制'
  },
  {
    id: 2,
    filename: 'recording_20250116_091545.mp4',
    streamName: 'main_stream',
    startTime: '2025-01-16 09:15:45',
    endTime: '2025-01-16 10:22:33',
    duration: '1小时06分48秒',
    fileSize: '1.8GB',
    status: 'completed',
    thumbnail: '/api/recordings/thumbnails/recording_20250116_091545.jpg',
    description: '早间安全巡检录制'
  },
  {
    id: 3,
    filename: 'recording_20250115_160830.mp4',
    streamName: 'main_stream',
    startTime: '2025-01-15 16:08:30',
    endTime: '2025-01-15 17:15:42',
    duration: '1小时07分12秒',
    fileSize: '1.9GB',
    status: 'completed',
    thumbnail: '/api/recordings/thumbnails/recording_20250115_160830.jpg',
    description: '下午环境监测录制'
  },
  {
    id: 4,
    filename: 'recording_20250115_140012.mp4',
    streamName: 'main_stream',
    startTime: '2025-01-15 14:00:12',
    endTime: '2025-01-15 14:45:28',
    duration: '45分16秒',
    fileSize: '1.2GB',
    status: 'completed',
    thumbnail: '/api/recordings/thumbnails/recording_20250115_140012.jpg',
    description: '午间休息时段监控'
  },
  {
    id: 5,
    filename: 'recording_20250115_103045.mp4',
    streamName: 'main_stream',
    startTime: '2025-01-15 10:30:45',
    endTime: '2025-01-15 11:45:12',
    duration: '1小时14分27秒',
    fileSize: '2.1GB',
    status: 'completed',
    thumbnail: '/api/recordings/thumbnails/recording_20250115_103045.jpg',
    description: '上午工作时段录制'
  }
])
const isLoadingRecordings = ref(false)
const currentPage = ref(1)
const pageSize = ref(12)
const totalPages = ref(1)
const filterStartDate = ref('')
const filterEndDate = ref('')
const filterStreamName = ref('')
// 视频播放器相关
const showVideoPlayer = ref(false)
const currentVideoUrl = ref('')
const currentVideoInfo = ref({})

// 监控回放相关数据
const selectedDate = ref(new Date().toISOString().split('T')[0])
const currentPlaybackSegment = ref(null)
const isPlayingPlayback = ref(false)
const playbackSpeed = ref(1)

// SLAM建图模拟数据
const slamMaps = ref([
  {
    id: 1,
    name: '智能看护区域A',
    description: '主要护理区域的三维地图',
    createdDate: '2025-01-15 10:30:00',
    lastUpdated: '2025-01-16 14:25:00',
    status: 'completed',
    keyframes: 1247,
    mapPoints: 8934,
    trajectoryLength: '2.3km',
    accuracy: 98.7,
    thumbnail: '/api/slam/maps/map_001_thumb.jpg',
    fileSize: '45.2MB',
    tags: ['护理区', '主要区域', '高精度']
  },
  {
    id: 2,
    name: '仓库区域B',
    description: '医疗设备仓库的三维地图',
    createdDate: '2025-01-14 15:45:00',
    lastUpdated: '2025-01-15 09:20:00',
    status: 'completed',
    keyframes: 856,
    mapPoints: 6234,
    trajectoryLength: '1.8km',
    accuracy: 97.2,
    thumbnail: '/api/slam/maps/map_002_thumb.jpg',
    fileSize: '32.1MB',
    tags: ['仓库', '设备区', '中等精度']
  },
  {
    id: 3,
    name: '办公室区域C',
    description: '行政办公区域的三维地图',
    createdDate: '2025-01-13 11:20:00',
    lastUpdated: '2025-01-16 08:15:00',
    status: 'in_progress',
    keyframes: 423,
    mapPoints: 3124,
    trajectoryLength: '1.2km',
    accuracy: 95.8,
    thumbnail: '/api/slam/maps/map_003_thumb.jpg',
    fileSize: '18.7MB',
    tags: ['办公区', '进行中', '待完善']
  },
  {
    id: 4,
    name: '紧急通道D',
    description: '紧急疏散通道的三维地图',
    createdDate: '2025-01-12 16:30:00',
    lastUpdated: '2025-01-14 12:45:00',
    status: 'completed',
    keyframes: 234,
    mapPoints: 1876,
    trajectoryLength: '0.8km',
    accuracy: 99.1,
    thumbnail: '/api/slam/maps/map_004_thumb.jpg',
    fileSize: '12.3MB',
    tags: ['紧急通道', '高精度', '安全区域']
  },
  {
    id: 5,
    name: '停车场区域E',
    description: '员工停车场的三维地图',
    createdDate: '2025-01-11 09:15:00',
    lastUpdated: '2025-01-13 17:30:00',
    status: 'pending',
    keyframes: 156,
    mapPoints: 1123,
    trajectoryLength: '0.6km',
    accuracy: 94.5,
    thumbnail: '/api/slam/maps/map_005_thumb.jpg',
    fileSize: '8.9MB',
    tags: ['停车场', '待处理', '低精度']
  }
])

// SLAM统计信息
const slamStats = ref({
  totalMaps: 5,
  completedMaps: 3,
  inProgressMaps: 1,
  pendingMaps: 1,
  totalKeyframes: 2916,
  totalMapPoints: 21291,
  averageAccuracy: 97.1,
  totalTrajectoryLength: '6.7km'
})

// 系统统计信息模拟数据
const systemStats = ref({
  totalRecordings: 5,
  totalSessions: 12,
  activeSessions: 2,
  completedMaps: 3,
  totalFaces: 5,
  activeFaces: 4,
  systemUptime: '15天8小时32分',
  cpuUsage: 45.2,
  memoryUsage: 68.7,
  diskUsage: 23.4,
  networkLatency: 12.5
})

// 侧边栏切换方法
const toggleSidebar = () => {
  sidebarCollapsed.value = !sidebarCollapsed.value
}

// 计算属性
const todayDate = computed(() => {
  return new Date().toISOString().split('T')[0]
})

const formatSelectedDate = computed(() => {
  if (!selectedDate.value) return '今天'
  const date = new Date(selectedDate.value)
  const today = new Date()
  const yesterday = new Date(today)
  yesterday.setDate(yesterday.getDate() - 1)
  
  if (date.toDateString() === today.toDateString()) {
    return '今天'
  } else if (date.toDateString() === yesterday.toDateString()) {
    return '昨天'
  } else {
    return date.toLocaleDateString('zh-CN', { 
      year: 'numeric', 
      month: 'long', 
      day: 'numeric',
      weekday: 'long'
    })
  }
})

const isNextDayDisabled = computed(() => {
  if (!selectedDate.value) return true
  const selected = new Date(selectedDate.value)
  const today = new Date()
  return selected >= today
})

// 当前设备
const currentDevice = reactive({
  id: 'HC-2023005',
  location: '老年公寓B栋',
  status: '运行中'
})


// 方法

/**
 * 通用视频播放错误处理函数
 * @param {Error} error - 播放错误对象
 * @param {HTMLVideoElement} video - 视频元素
 * @param {string} context - 错误上下文描述
 */
const handleVideoPlayError = (error, video, context = '') => {
  console.log(`🎥 视频播放错误处理 [${context}]:`, error)
  
  if (error.name === 'NotAllowedError') {
    console.warn('⚠️ 视频播放被浏览器阻止，需要用户交互')
  } else if (error.name === 'AbortError') {
    console.warn('⚠️ 视频播放被中断，正在重试...')
    setTimeout(() => {
      video.play().catch(err => console.warn(`重试播放失败 [${context}]:`, err))
    }, 100)
  } else {
    console.error(`❌ 视频播放失败 [${context}]:`, error)
  }
}

/**
 * 尝试播放视频的通用函数
 * @param {HTMLVideoElement} video - 视频元素
 * @param {string} context - 播放上下文描述
 * @returns {Promise<boolean>} 播放是否成功
 */
const tryPlayVideo = async (video, context = '') => {
  try {
    await safePlayVideo(video, { muted: false })
    console.log(`✅ 视频播放成功 [${context}]`)
    return true
  } catch (error) {
    console.error(`❌ 视频播放失败 [${context}]:`, error)
    return false
  }
}

/**
 * 防抖函数 - 延迟执行，如果在延迟期间再次调用则重新计时
 * @param {Function} func - 要防抖的函数
 * @param {number} wait - 延迟时间（毫秒）
 * @returns {Function} 防抖后的函数
 */
const debounce = (func, wait) => {
  let timeout
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout)
      func(...args)
    }
    clearTimeout(timeout)
    timeout = setTimeout(later, wait)
  }
}

/**
 * 节流函数 - 限制函数执行频率，在指定时间内最多执行一次
 * @param {Function} func - 要节流的函数
 * @param {number} limit - 时间间隔（毫秒）
 * @returns {Function} 节流后的函数
 */
const throttle = (func, limit) => {
  let inThrottle
  return function(...args) {
    if (!inThrottle) {
      func.apply(this, args)
      inThrottle = true
      setTimeout(() => inThrottle = false, limit)
    }
  }
}

// 启动录制回放工作线程
const startRecordingPlaybackWorker = () => {
  console.log('🚀 启动录制回放工作线程...')
  isRecordingPlaybackActive.value = true
  
  recordingPlaybackWorker.value = setInterval(async () => {
    if (!isRecordingPlaybackActive.value) {
      console.log('⏹️ 录制回放工作线程已停止')
      return
    }
    
    // 录制回放相关的后台任务
    if (activeTab.value === 'recordings') {
      console.log('📹 录制回放工作线程执行中...')
      
      // 可以在这里添加录制回放相关的后台任务
      // 比如：检查录制文件状态、更新录制列表等
      try {
        // 示例：定期检查录制文件状态
        // await checkRecordingFilesStatus()
        console.log('✅ 录制回放工作线程执行完成')
      } catch (error) {
        console.error('❌ 录制回放工作线程执行失败:', error)
      }
    }
  }, 10000) // 每10秒执行一次
}

// 停止录制回放工作线程
const stopRecordingPlaybackWorker = () => {
  console.log('⏹️ 停止录制回放工作线程...')
  isRecordingPlaybackActive.value = false
  
  if (recordingPlaybackWorker.value) {
    clearInterval(recordingPlaybackWorker.value)
    recordingPlaybackWorker.value = null
  }
}

// 启动视频流保持机制
const startVideoStreamKeepAlive = () => {
  console.log('🔄 启动视频流保持机制...')
  
  videoStreamKeepAlive.value = setInterval(() => {
    if (mainVideo.value && webrtcConnection.value) {
      const video = mainVideo.value
      
      // 检查WebRTC连接状态
      if (webrtcConnection.value.connectionState === 'connected' || 
          webrtcConnection.value.connectionState === 'connecting') {
        // 连接正常，检查视频流
        if (!video.srcObject && !video.src) {
          console.log('🔄 视频元素没有流，尝试重新设置...')
          // 尝试从WebRTC连接获取流
          if (webrtcConnection.value.getReceivers) {
            const receivers = webrtcConnection.value.getReceivers()
            const videoReceiver = receivers.find(r => r.track && r.track.kind === 'video')
            if (videoReceiver && videoReceiver.track) {
              console.log('🔄 从WebRTC接收器重新设置视频流...')
              const stream = new MediaStream([videoReceiver.track])
              video.srcObject = stream
              tryPlayVideo(video, '视频流保持机制')
            }
          }
        } else if (video.srcObject && video.paused) {
          console.log('🔄 视频暂停了，尝试播放...')
          tryPlayVideo(video, '视频流保持机制-恢复播放')
        }
      } else {
        // 连接断开，尝试重连
        console.log('🔄 WebRTC连接断开，尝试重连...')
        autoConnectVideoStream(true)
      }
    }
  }, 5000) // 每5秒检查一次
}

// 停止视频流保持机制
const stopVideoStreamKeepAlive = () => {
  console.log('⏹️ 停止视频流保持机制...')
  
  if (videoStreamKeepAlive.value) {
    clearInterval(videoStreamKeepAlive.value)
    videoStreamKeepAlive.value = null
  }
}

// 强制恢复视频流
const forceRestoreVideoStream = async () => {
  console.log('🔄 强制恢复视频流...')
  
  if (!mainVideo.value || !webrtcConnection.value) {
    console.log('❌ 视频元素或WebRTC连接不存在')
    return false
  }
  
  const video = mainVideo.value
  const pc = webrtcConnection.value
  
  // 检查WebRTC连接状态
  if (pc.connectionState === 'connected') {
    // 尝试从接收器获取视频流
    if (pc.getReceivers) {
      const receivers = pc.getReceivers()
      const videoReceiver = receivers.find(r => r.track && r.track.kind === 'video')
      
      if (videoReceiver && videoReceiver.track) {
        console.log('✅ 找到视频轨道，重新设置流...')
        const stream = new MediaStream([videoReceiver.track])
        video.srcObject = stream
        
        // 使用安全播放
        try {
          await safePlayVideo(video, { muted: false })
          console.log('✅ 视频流恢复成功')
          connectionStatus.value = '已连接'
        } catch (error) {
          console.error('❌ 视频播放失败:', error)
        }
        return true
      } else {
        console.log('❌ 未找到视频轨道')
      }
    }
  } else {
    console.log('❌ WebRTC连接未就绪:', pc.connectionState)
  }
  
  return false
}

// 录制相关方法
const refreshRecordings = async () => {
  await loadRecordings()
}

// 监控回放相关方法
const loadRecordingsByDate = async (date) => {
  try {
    isLoadingRecordings.value = true
    const response = await fetch(buildUrls.recordingApi(`/api/recording/by-date?startDate=${date}&endDate=${date}`))
    const result = await response.json()
    
    if (result.code === 200) {
      recordings.value = result.data || []
      console.log('按日期加载录制文件成功:', result.data)
    } else {
      console.error('按日期加载录制文件失败:', result.message)
      recordings.value = []
    }
  } catch (error) {
    console.error('按日期加载录制文件失败:', error)
    recordings.value = []
  } finally {
    isLoadingRecordings.value = false
  }
}



const playPlaybackRecording = (recording) => {
  console.log('播放回放录制:', recording)
  currentPlaybackSegment.value = recording
  currentVideoUrl.value = buildUrls.recording(recording.filePath)
  currentVideoInfo.value = {
    title: `监控回放 - ${formatDateTime(recording.startTime)}`,
    duration: formatTime(recording.duration),
    fileSize: formatFileSize(recording.fileSize),
    filePath: recording.filePath,
    startTime: recording.startTime,
    endTime: recording.endTime
  }
  showVideoPlayer.value = true
}

const goToToday = () => {
  selectedDate.value = new Date().toISOString().split('T')[0]
  loadRecordingsByDate(selectedDate.value)
}

const goToPreviousDay = () => {
  const date = new Date(selectedDate.value)
  date.setDate(date.getDate() - 1)
  selectedDate.value = date.toISOString().split('T')[0]
  loadRecordingsByDate(selectedDate.value)
}

const goToNextDay = () => {
  if (isNextDayDisabled.value) return
  
  const date = new Date(selectedDate.value)
  date.setDate(date.getDate() + 1)
  const tomorrow = date.toISOString().split('T')[0]
  const today = new Date().toISOString().split('T')[0]
  
  // 确保不能超过今天
  if (tomorrow <= today) {
    selectedDate.value = tomorrow
    loadRecordingsByDate(selectedDate.value)
  }
}

const onDateChange = () => {
  // 验证选择的日期不能超过今天
  const selected = new Date(selectedDate.value)
  const today = new Date()
  today.setHours(23, 59, 59, 999) // 设置为今天的最后一刻
  
  if (selected > today) {
    // 如果选择的日期超过今天，重置为今天
    selectedDate.value = new Date().toISOString().split('T')[0]
    console.warn('⚠️ 不能选择未来的日期，已重置为今天')
  }
  
  loadRecordingsByDate(selectedDate.value)
}



const loadRecordings = async () => {
  try {
    isLoadingRecordings.value = true
    
    // 默认加载今天的录像
    const today = new Date().toISOString().split('T')[0]
    const targetDate = selectedDate.value || today
    
    const url = buildUrls.recordingApi(`/api/recording/by-date?startDate=${targetDate}&endDate=${targetDate}`)
    
    const response = await fetch(url)
    const result = await response.json()
    
    if (result.code === 200) {
      recordings.value = result.data || []
      // 计算总页数
      if (result.total) {
        totalPages.value = Math.ceil(result.total / pageSize.value)
      }
    } else {
      console.error('加载录制列表失败:', result.message)
    }
  } catch (error) {
    console.error('加载录制列表失败:', error)
  } finally {
    isLoadingRecordings.value = false
  }
}



const startRecording = async () => {
  try {
    const response = await fetch(buildUrls.api('/schedule01/videoRecording/startRecording?streamName=livestream'), {
      method: 'POST'
    })
    const result = await response.json()
    
    if (result.code === 200) {
      alert('录制开始成功')
      await refreshRecordings()
    } else {
      alert('录制开始失败: ' + result.message)
    }
  } catch (error) {
    console.error('开始录制失败:', error)
    alert('开始录制失败: ' + error.message)
  }
}

const playRecording = (recording) => {
  // 注释：检查文件是否为临时文件，如果是则不允许播放
  // if (recording.filePath && recording.filePath.endsWith('.mp4.tmp')) {
  //   console.log('文件仍在录制中，无法播放:', recording.filePath);
  //   // 可以显示一个提示消息
  //   alert('文件仍在录制中，请等待录制完成后再播放');
  //   return;
  // }
  
  // 设置视频信息并打开播放器
  currentVideoUrl.value = buildUrls.recording(recording.filePath)
  currentVideoInfo.value = {
    title: `监控回放 - ${formatDateTime(recording.startTime)}`,
    duration: formatDuration(recording.duration),
    fileSize: formatFileSize(recording.fileSize),
    filePath: recording.filePath,
    startTime: recording.startTime,
    endTime: recording.endTime
  }
  showVideoPlayer.value = true
}

const downloadRecording = (recording) => {
  const videoUrl = buildUrls.recording(recording.filePath)
  const link = document.createElement('a')
  link.href = videoUrl
  link.download = `${recording.streamName}_${recording.startTime}.mp4.tmp`
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}


const searchRecordings = async () => {
  currentPage.value = 1
  await loadRecordings()
}

const prevPage = () => {
  if (currentPage.value > 1) {
    currentPage.value--
    loadRecordings()
  }
}

const nextPage = () => {
  if (currentPage.value < totalPages.value) {
    currentPage.value++
    loadRecordings()
  }
}

// 工具方法
const formatFileSize = (bytes) => {
  if (!bytes) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 获取文件格式显示名称
const getFileFormatDisplay = (filePath) => {
  if (!filePath) return '未知格式'
  if (filePath.endsWith('.mp4.tmp')) return 'MP4 (临时)'
  if (filePath.endsWith('.mp4')) return 'MP4'
  if (filePath.endsWith('.flv')) return 'FLV'
  if (filePath.endsWith('.avi')) return 'AVI'
  if (filePath.endsWith('.mov')) return 'MOV'
  return '视频文件'
}

const formatDuration = (seconds) => {
  if (!seconds) return '00:00'
  const hours = Math.floor(seconds / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)
  const secs = seconds % 60
  
  if (hours > 0) {
    return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
  } else {
    return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
  }
}

const formatDateTime = (dateTime) => {
  if (!dateTime) return ''
  return new Date(dateTime).toLocaleString('zh-CN')
}

const getStatusText = (status) => {
  const statusMap = {
    'recording': '录制中',
    'completed': '已完成',
    'failed': '失败',
    'deleted': '已删除'
  }
  return statusMap[status] || status
}

const getStatusClass = (status) => {
  const classMap = {
    'recording': 'bg-red-500 text-white',
    'completed': 'bg-green-500 text-white',
    'failed': 'bg-yellow-500 text-white',
    'deleted': 'bg-gray-500 text-white'
  }
  return classMap[status] || 'bg-gray-500 text-white'
}

// 监控系统相关方法


const previousDay = () => {
  const date = new Date(selectedDate.value || new Date())
  date.setDate(date.getDate() - 1)
  selectedDate.value = date.toISOString().split('T')[0]
  loadRecordingsByDate(selectedDate.value)
}

const nextDay = () => {
  if (isNextDayDisabled.value) return
  
  const date = new Date(selectedDate.value || new Date())
  date.setDate(date.getDate() + 1)
  const tomorrow = date.toISOString().split('T')[0]
  const today = new Date().toISOString().split('T')[0]
  
  // 确保不能超过今天
  if (tomorrow <= today) {
    selectedDate.value = tomorrow
    loadRecordingsByDate(selectedDate.value)
  }
}




const formatTime = (dateTime) => {
  if (!dateTime) return '00:00'
  const date = new Date(dateTime)
  return date.toLocaleTimeString('zh-CN', { 
    hour12: false, 
    hour: '2-digit', 
    minute: '2-digit' 
  })
}


// 检查流状态
const checkStreamStatus = async () => {
  try {
    // 直接检查流状态API
    const response = await fetch(buildUrls.srsApi('/rtc/v1/streams/'), {
      method: 'GET',
      timeout: 5000
    })
    
    if (response.ok) {
      const data = await response.json()
      console.log('流状态检查结果:', data)
      
      // 检查是否有streams字段且不为空
      if (data.streams && Array.isArray(data.streams) && data.streams.length > 0) {
        console.log('✅ 检测到活跃流:', data.streams)
        connectionStatus.value = '检测到流，正在连接...'
        hasError.value = false
        isLoading.value = true
        connectWebRTC()
        return true
      } else {
        console.log('⚠️ 没有检测到活跃流，但尝试直接连接WebRTC...')
        // 即使没有检测到流，也尝试连接（WebRTC推流可能正在进行中）
        connectionStatus.value = '尝试WebRTC连接...'
        hasError.value = false
        isLoading.value = true
        connectWebRTC()
        return true
      }
    } else {
      console.log('流状态检查失败:', response.status)
      return false
    }
  } catch (error) {
    console.error('检查流状态失败:', error)
    return false
  }
}

// 流状态监控
let streamCheckInterval = null
const startStreamMonitoring = () => {
  if (streamCheckInterval) {
    clearInterval(streamCheckInterval)
  }
  
  console.log('🔄 启动流状态监控...')
  streamCheckInterval = setInterval(async () => {
    try {
      // 检查是否有活跃流
      const response = await fetch(buildUrls.srsApi('/rtc/v1/streams/'), {
        method: 'GET',
        timeout: 5000
      })
      
      if (response.ok) {
        const data = await response.json()
        console.log('流状态监控检查:', data)
        
        // 如果有流，尝试连接
        if (data.streams && Array.isArray(data.streams) && data.streams.length > 0) {
          console.log('✅ 检测到活跃流，尝试连接...')
          clearInterval(streamCheckInterval)
          streamCheckInterval = null
          connectionStatus.value = '检测到流，正在连接...'
          hasError.value = false
          isLoading.value = true
          connectWebRTC()
        } else {
          console.log('⏳ 等待推流...')
          connectionStatus.value = '等待推流...'
        }
      }
    } catch (error) {
      console.log('流状态检查失败:', error.message)
    }
  }, 3000) // 每3秒检查一次
}

const stopStreamMonitoring = () => {
  if (streamCheckInterval) {
    clearInterval(streamCheckInterval)
    streamCheckInterval = null
  }
}

// 人脸识别相关方法
const toggleFaceRecognition = () => {
  faceRecognitionEnabled.value = !faceRecognitionEnabled.value
  
  if (faceRecognitionEnabled.value) {
    startFaceDetection()
    console.log('✅ 人脸识别已启用')
    console.log('📹 视频状态:', {
      paused: mainVideo.value?.paused,
      readyState: mainVideo.value?.readyState,
      videoWidth: mainVideo.value?.videoWidth,
      videoHeight: mainVideo.value?.videoHeight
    })
  } else {
    stopFaceDetection()
    detectedFaces.value = []
    console.log('❌ 人脸识别已禁用')
  }
}

// YOLO目标检测相关函数
const toggleYOLODetection = () => {
  yoloDetectionEnabled.value = !yoloDetectionEnabled.value
  
  if (yoloDetectionEnabled.value) {
    startYOLODetection()
    console.log('✅ YOLO目标检测已启用')
  } else {
    // 立即清空检测结果，确保UI立即更新
    detectedObjects.value = []
    // 强制触发响应式更新
    detectedObjects.value = []
    stopYOLODetection()
    console.log('❌ YOLO目标检测已禁用')
  }
}

const startYOLODetection = () => {
  if (yoloDetectionInterval.value) {
    clearInterval(yoloDetectionInterval.value)
  }
  
  console.log('🎯 启动YOLO检测定时器...')
  
  // 每秒检测一次目标
  yoloDetectionInterval.value = setInterval(async () => {
    if (!yoloDetectionEnabled.value || !mainVideo.value) {
      console.log('⚠️ YOLO检测跳过: 未启用或视频未就绪')
      // 如果YOLO检测被禁用，自动清理定时器
      if (!yoloDetectionEnabled.value) {
        clearInterval(yoloDetectionInterval.value)
        yoloDetectionInterval.value = null
        console.log('🧹 YOLO检测定时器已自动清理')
      }
      return
    }
    
    // 更新检测时间
    lastYoloDetectionTime.value = Date.now()
    
    console.log('🎯 开始YOLO目标检测...')
    
    try {
      // 获取视频帧
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      canvas.width = mainVideo.value.videoWidth
      canvas.height = mainVideo.value.videoHeight
      ctx.drawImage(mainVideo.value, 0, 0)
      
      console.log(`📷 视频帧尺寸: ${canvas.width} x ${canvas.height}`)
      
      // 转换为Blob
      const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/jpeg', 0.8))
      
      console.log(`📦 图像数据大小: ${blob.size} bytes`)
      
      // 调用YOLO检测
      console.log('🚀 发送YOLO检测请求...')
      console.log(`🎯 当前阈值设置: ${yoloConfidenceThreshold.value} (${Math.round(yoloConfidenceThreshold.value * 100)}%)`)
      const response = await yoloApiClient.detectObjects(blob, yoloConfidenceThreshold.value)
      console.log(`📊 YOLO检测响应:`, response)
      
      // 从响应中提取objects数组
      const results = response && response.objects ? response.objects : []
      console.log(`📊 提取的检测结果: ${results.length} 个目标`)
      
      // 调整坐标比例以适应视频显示尺寸
      const video = mainVideo.value
      const videoRect = video.getBoundingClientRect()
      const scaleX = videoRect.width / canvas.width
      const scaleY = videoRect.height / canvas.height
      
      // 直接使用后端返回的结果（已经按阈值过滤）
      detectedObjects.value = results.map(object => ({
        ...object,
        x: object.x * scaleX,
        y: object.y * scaleY,
        width: object.w * scaleX,
        height: object.h * scaleY
      }))
      
      console.log(`🎯 YOLO检测结果: ${results.length} 个目标 (阈值: ${Math.round(yoloConfidenceThreshold.value * 100)}%)`)
    } catch (error) {
      console.error('YOLO检测失败:', error)
    }
  }, 1000) // 每秒检测一次YOLO目标
}

const stopYOLODetection = () => {
  if (yoloDetectionInterval.value) {
    clearInterval(yoloDetectionInterval.value)
    yoloDetectionInterval.value = null
    console.log('🧹 YOLO检测定时器已清理')
  }
  
  // 清空检测结果
  detectedObjects.value = []
  lastYoloDetectionTime.value = 0
  
  console.log('❌ YOLO检测已完全停止')
}


const startFaceDetection = () => {
  if (faceDetectionInterval.value) {
    clearInterval(faceDetectionInterval.value)
  }
  
  // 动态检测间隔：有用户时1秒，无用户时2.5秒
  const runDetection = async () => {
    if (!faceRecognitionEnabled.value || !mainVideo.value) {
      return
    }
    
    // 检查视频是否真正准备好（不依赖UI的暂停状态）
    if (mainVideo.value.readyState < 2 || mainVideo.value.videoWidth === 0) {
      console.log('⚠️ 视频未准备好，跳过人脸检测')
      return
    }
    
    try {
      await detectFacesInCurrentFrame()
    } catch (error) {
      console.error('人脸检测失败:', error)
    }
    
    // 根据检测结果动态调整下次检测间隔
    adjustDetectionInterval()
  }
  
  // 立即执行一次检测
  runDetection()
  
  // 设置定时器
  faceDetectionInterval.value = setInterval(runDetection, currentDetectionInterval.value)
}

const stopFaceDetection = () => {
  if (faceDetectionInterval.value) {
    clearInterval(faceDetectionInterval.value)
    faceDetectionInterval.value = null
  }
}

// 动态调整检测间隔
const adjustDetectionInterval = () => {
  const hasFaces = detectedFaces.value && detectedFaces.value.length > 0
  const newInterval = hasFaces ? 1000 : 2500 // 有用户时1秒，无用户时2.5秒
  
  if (newInterval !== currentDetectionInterval.value) {
    console.log(`🔄 调整人脸检测间隔: ${currentDetectionInterval.value}ms -> ${newInterval}ms (检测到${detectedFaces.value.length}个人脸)`)
    currentDetectionInterval.value = newInterval
    
    // 重新设置定时器
    if (faceDetectionInterval.value) {
      clearInterval(faceDetectionInterval.value)
      faceDetectionInterval.value = setInterval(async () => {
        if (!faceRecognitionEnabled.value || !mainVideo.value) {
          return
        }
        
        if (mainVideo.value.readyState < 2 || mainVideo.value.videoWidth === 0) {
          console.log('⚠️ 视频未准备好，跳过人脸检测')
          return
        }
        
        try {
          await detectFacesInCurrentFrame()
        } catch (error) {
          console.error('人脸检测失败:', error)
        }
        
        adjustDetectionInterval()
      }, currentDetectionInterval.value)
    }
  }
}

const detectFacesInCurrentFrame = async () => {
  try {
    const video = mainVideo.value
    if (!video || video.videoWidth === 0 || video.videoHeight === 0) {
      console.log('⚠️ 视频未准备好，跳过人脸检测')
      return
    }
    
    // 检查视频是否真正准备好（不依赖UI的暂停状态）
    if (video.readyState < 2) {
      console.log('⚠️ 视频readyState不足，跳过人脸检测')
      return
    }
    
    console.log('🔍 开始人脸检测...')
    console.log('📹 视频信息:', {
      width: video.videoWidth,
      height: video.videoHeight,
      readyState: video.readyState,
      paused: video.paused,
      currentTime: video.currentTime
    })
    
    // 创建canvas来捕获当前帧
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    canvas.width = video.videoWidth
    canvas.height = video.videoHeight
    
    // 绘制当前视频帧到canvas
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
    console.log('🖼️ Canvas尺寸:', canvas.width, 'x', canvas.height)
    
    // 转换为灰度图像以提高检测效果
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
    const data = imageData.data
    
    // 转换为灰度
    for (let i = 0; i < data.length; i += 4) {
      const gray = data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114
      data[i] = gray     // R
      data[i + 1] = gray // G
      data[i + 2] = gray // B
      // data[i + 3] 保持 Alpha 通道不变
    }
    
    ctx.putImageData(imageData, 0, 0)
    console.log('🖼️ 已转换为灰度图像')
    
    // 转换为blob并发送到后端进行人脸检测
    canvas.toBlob(async (blob) => {
      if (!blob) {
        console.log('❌ Canvas转换为blob失败')
        return
      }
      
      console.log('📤 发送图像数据:', {
        blobSize: blob.size,
        blobType: blob.type,
        canvasSize: `${canvas.width}x${canvas.height}`
      })
      
      const formData = new FormData()
      formData.append('image', blob, 'frame.jpg')
      
      try {
        const response = await fetch(getApiUrl('detectFaces'), {
          method: 'POST',
          body: formData
        })
        
        if (response.ok) {
          const result = await response.json()
          console.log('📊 人脸检测API响应:', result)
          console.log('🔍 检测到人脸数量:', result.data ? result.data.length : 0)
          if (result.code === 200 && result.data) {
            // 调整坐标比例以适应视频显示尺寸
            const videoRect = video.getBoundingClientRect()
            const scaleX = videoRect.width / canvas.width
            const scaleY = videoRect.height / canvas.height
            
            detectedFaces.value = result.data.map(face => ({
              ...face,
              x: face.x * scaleX,
              y: face.y * scaleY,
              width: face.width * scaleX,
              height: face.height * scaleY
            }))
            console.log('✅ 检测到人脸:', detectedFaces.value.length, '个')
          } else {
            detectedFaces.value = []
            console.log('❌ 未检测到人脸')
          }
        } else {
          console.error('❌ API调用失败:', response.status, response.statusText)
        }
      } catch (error) {
        console.error('人脸检测API调用失败:', error)
        detectedFaces.value = []
      }
      
      // 检测完成后调整检测间隔
      adjustDetectionInterval()
    }, 'image/jpeg', 0.8)
    
  } catch (error) {
    console.error('捕获视频帧失败:', error)
    detectedFaces.value = []
    // 出错时也调整检测间隔
    adjustDetectionInterval()
  }
}


const toggleFullscreen = () => {
  const videoContainer = document.querySelector('.aspect-video')
  if (!videoContainer) return
  
  if (!document.fullscreenElement) {
    // 进入全屏
    if (videoContainer.requestFullscreen) {
      videoContainer.requestFullscreen()
    } else if (videoContainer.webkitRequestFullscreen) {
      videoContainer.webkitRequestFullscreen()
    } else if (videoContainer.msRequestFullscreen) {
      videoContainer.msRequestFullscreen()
    }
  } else {
    // 退出全屏
    if (document.exitFullscreen) {
      document.exitFullscreen()
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen()
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen()
    }
  }
}

const togglePlayPause = () => {
  isPlaying.value = !isPlaying.value
  if (mainVideo.value) {
    if (isPlaying.value) {
      mainVideo.value.play()
    } else {
      mainVideo.value.pause()
    }
  }
  console.log('切换播放/暂停:', isPlaying.value)
}

// 刷新视频流
const refreshVideoStream = () => {
  console.log('🔄 手动刷新视频流...')
  
  // 先尝试强制恢复视频流
  if (!forceRestoreVideoStream()) {
    // 如果恢复失败，重新连接
    console.log('🔄 强制恢复失败，重新连接视频流...')
    autoConnectVideoStream(true) // 强制重连
  }
}

// 点击外部关闭音量控制
const handleClickOutside = (event) => {
  if (showVolumeControl.value && !event.target.closest('.volume-control-container')) {
    showVolumeControl.value = false
  }
}

// 切换音量控制显示
const toggleVolumeControl = () => {
  if (showVolumeControl.value) {
    // 如果音量控制已显示，点击后归零
    volume.value = 0
    updateVolume()
  }
  showVolumeControl.value = !showVolumeControl.value
  console.log('切换音量控制显示:', showVolumeControl.value)
}

// 切换静音状态
const toggleMute = () => {
  isMuted.value = !isMuted.value
  if (mainVideo.value) {
    mainVideo.value.muted = isMuted.value
  }
  console.log('切换静音状态:', isMuted.value)
}

// 更新音量
const updateVolume = () => {
  if (mainVideo.value) {
    mainVideo.value.volume = volume.value / 100
    // 如果音量大于0，取消静音
    if (volume.value > 0 && isMuted.value) {
      isMuted.value = false
      mainVideo.value.muted = false
    }
    // 如果音量为0，设置为静音
    if (volume.value === 0 && !isMuted.value) {
      isMuted.value = true
      mainVideo.value.muted = true
    }
  }
  console.log('更新音量:', volume.value)
}

const handleVideoCanPlay = () => {
  console.log('🎥 视频可以播放')
  isLoading.value = false
  hasError.value = false
  connectionStatus.value = '已连接'
  isPlaying.value = true
  
  // 启动YOLO检测
  if (yoloDetectionEnabled.value) {
    startYOLODetection()
    console.log('🎯 YOLO检测已自动启动')
  }
  
  // 确保视频正在播放
  if (mainVideo.value) {
    const video = mainVideo.value
    
    // 设置音量和静音状态
    video.volume = volume.value / 100
    video.muted = isMuted.value
    
    console.log('视频状态:', {
      paused: video.paused,
      readyState: video.readyState,
      srcObject: !!video.srcObject,
      currentTime: video.currentTime,
      videoWidth: video.videoWidth,
      videoHeight: video.videoHeight,
      volume: video.volume,
      muted: video.muted
    })
    
    // 验证视频内容
    validateVideoContent(video)
    
    // 如果视频暂停了，尝试播放
    if (video.paused) {
      video.play().then(() => {
        console.log('✅ 视频自动播放成功')
      }).catch(error => {
        console.error('❌ 视频自动播放失败:', error)
      })
    }
    
    // 启动视频流监控
    startVideoMonitoring()
  }
}

// 验证视频内容
const validateVideoContent = (video) => {
  console.log('🔍 验证视频内容...')
  
  // 检查视频尺寸
  if (video.videoWidth === 0 || video.videoHeight === 0) {
    console.warn('⚠️ 视频尺寸为0，可能没有视频内容')
    setTimeout(() => {
      if (video.videoWidth === 0 || video.videoHeight === 0) {
        console.error('❌ 视频内容验证失败，尝试重新连接')
        autoConnectVideoStream(true)
      }
    }, 3000)
  } else {
    console.log('✅ 视频内容验证成功:', video.videoWidth, 'x', video.videoHeight)
  }
  
  // 检查视频流
  if (!video.srcObject) {
    console.warn('⚠️ 视频没有srcObject')
  } else {
    console.log('✅ 视频srcObject存在')
  }
  
  // 检查视频是否真正在播放
  setTimeout(() => {
    if (video.currentTime === 0 && video.readyState >= 2) {
      console.warn('⚠️ 视频时间没有推进，可能卡住了')
    }
  }, 2000)
}

const handleVideoError = () => {
  isLoading.value = false
  hasError.value = true
  errorMessage.value = '视频加载失败，请检查网络连接'
  connectionStatus.value = '连接失败'
}

// 重置视频流连接
const resetVideoStream = (forceReset = false) => {
  console.log('🔄 重置视频流连接...', forceReset ? '(强制重置)' : '(保持连接)')
  
  // 只有在强制重置时才断开连接
  if (forceReset) {
    // 停止当前连接
    if (webrtcConnection.value) {
      webrtcConnection.value.close()
      webrtcConnection.value = null
    }
    
    // 清空视频元素
    if (mainVideo.value) {
      const video = mainVideo.value
      video.srcObject = null
      video.load()
    }
  }
  
  // 停止流监控
  if (streamCheckInterval) {
    clearInterval(streamCheckInterval)
    streamCheckInterval = null
  }
  
  // 重置状态
  connectionStatus.value = '连接中...'
  hasError.value = false
  isLoading.value = true
  errorMessage.value = ''
}

// 自动连接视频流
const autoConnectVideoStream = async (forceReconnect = false) => {
  try {
    console.log('🚀 开始自动连接视频流...', forceReconnect ? '(强制重连)' : '(保持连接)')
    
    // 检查是否已有连接
    if (!forceReconnect && mainVideo.value && connectionStatus.value === '已连接' && webrtcConnection.value) {
      console.log('✅ 视频流已连接，无需重新连接')
      return
    }
    
    // 先重置连接（根据参数决定是否强制重置）
    resetVideoStream(forceReconnect)
    
    // 等待一下确保重置完成
    await new Promise(resolve => setTimeout(resolve, 200))
    
    connectionStatus.value = '正在连接视频流...'
    
    // 直接尝试WebRTC连接（默认选择）
    console.log('🚀 使用WebRTC作为默认视频源...')
    connectionStatus.value = '正在连接WebRTC...'
    await connectWebRTC()
  } catch (error) {
    console.error('自动连接失败:', error)
    connectionStatus.value = '连接失败'
    errorMessage.value = '自动连接失败，请手动重试'
    hasError.value = true
    isLoading.value = false
  }
}

// 检查端口连通性
const checkPortConnectivity = async (host, port, timeout = 5000) => {
  try {
    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), timeout)
    
    const response = await fetch(`http://${host}:${port}/`, {
      method: 'HEAD',
      signal: controller.signal,
      mode: 'no-cors' // 避免CORS问题
    })
    
    clearTimeout(timeoutId)
    return true
  } catch (error) {
    // 如果是网络错误，说明端口可能关闭
    if (error.name === 'AbortError' || error.name === 'TypeError') {
      return false
    }
    // 其他错误也认为端口不可用
    return false
  }
}

// 检查SRS服务器状态和配置
const checkSRSServer = async () => {
  try {
    console.log('🔍 开始检查SRS服务器连通性...')
    
    // 检查各个端口的连通性
    const ports = [
      { port: 1985, name: 'SRS API端口' },
      { port: 8080, name: 'HLS端口' },
      { port: 1935, name: 'RTMP端口' },
      { port: 80, name: 'HTTP端口' }
    ]
    
    const connectivityResults = {}
    for (const { port, name } of ports) {
      console.log(`检查${name} (${port})...`)
      const isOpen = await checkPortConnectivity(config.srs.host, port)
      connectivityResults[port] = isOpen
      console.log(`${name} (${port}): ${isOpen ? '✅ 开放' : '❌ 关闭'}`)
    }
    
    // 检查服务器状态
    let streamsData = null
    let configData = null
    
    if (connectivityResults[1985]) {
      try {
        // 使用正确的SRS API端点
        const streamsResponse = await fetch(buildUrls.srsApi('/rtc/v1/streams/'), {
          method: 'GET',
          timeout: 5000
        })
        streamsData = await streamsResponse.json()
        console.log('SRS服务器流状态:', streamsData)
        
        // 检查服务器基本信息
        const serverResponse = await fetch(buildUrls.srsApi('/rtc/v1/streams/'), {
          method: 'GET',
          timeout: 5000
        })
        configData = await serverResponse.json()
        console.log('SRS服务器配置:', configData)
        
        // 检查服务器基本信息
        if (configData) {
          console.log('SRS服务器信息:', {
            server: configData.server,
            service: configData.service,
            pid: configData.pid,
            urls: configData.urls
          })
          
          // 检查WebRTC API是否可用
          if (configData.urls && configData.urls.rtc) {
            console.log('WebRTC API可用:', configData.urls.rtc)
          }
        }
      } catch (error) {
        console.error('SRS API调用失败:', error)
      }
    } else {
      console.warn('⚠️ SRS API端口1985不可访问，可能是阿里云安全组未开放')
    }
    
    return { 
      streams: streamsData, 
      config: configData, 
      connectivity: connectivityResults 
    }
  } catch (error) {
    console.error('检查SRS服务器失败:', error)
    return null
  }
}

// 测试SRS自带播放器方法
const testSRSPlayer = async () => {
  try {
    console.log('🧪 测试SRS自带播放器方法...')
    
    if (!mainVideo.value) return
    const video = mainVideo.value
    
    // 直接使用SRS自带播放器的URL格式
    const streamUrl = buildUrls.webrtc()
    console.log('测试流地址:', streamUrl)
    
    // 创建RTCPeerConnection
    const pc = new RTCPeerConnection({
      iceServers: [
        { urls: 'stun:stun.l.google.com:19302' },
        { urls: 'stun:stun1.l.google.com:19302' }
      ]
    })
    
    // 添加接收轨道，这样SDP才会包含媒体信息
    pc.addTransceiver('video', { direction: 'recvonly' })
    pc.addTransceiver('audio', { direction: 'recvonly' })
    
    webrtcConnection.value = pc
    
    pc.ontrack = async (event) => {
      console.log('✅ 收到远程流:', event.streams[0])
      console.log('设置视频流到video元素...')
      
      // 确保视频元素存在
      if (!video) {
        console.error('❌ 视频元素不存在')
        return
      }
      
      // 设置视频流
      video.srcObject = event.streams[0]
      
      // 使用安全播放
      try {
        await safePlayVideo(video, { muted: false })
        console.log('✅ 视频开始播放')
        handleVideoCanPlay()
      } catch (error) {
        console.error('❌ 视频播放失败:', error)
      }
    }
    
    // 等待视频元数据加载
    video.addEventListener('loadedmetadata', () => {
      console.log('📹 视频元数据加载完成')
      console.log('视频尺寸:', video.videoWidth, 'x', video.videoHeight)
      console.log('视频时长:', video.duration)
    })
    
    // 等待视频可以播放
    video.addEventListener('canplay', () => {
      console.log('🎬 视频可以播放')
      handleVideoCanPlay()
    })
    
    pc.oniceconnectionstatechange = () => {
      console.log('ICE连接状态:', pc.iceConnectionState)
      if (pc.iceConnectionState === 'connected') {
        connectionStatus.value = '已连接'
        isLoading.value = false
      } else if (pc.iceConnectionState === 'failed') {
        handleVideoError()
      }
    }
    
      // 创建offer
      const offer = await pc.createOffer()
      
      // 修改SDP以支持BUNDLE
      let sdp = offer.sdp
      if (!sdp.includes('a=group:BUNDLE')) {
        // 添加BUNDLE组
        const lines = sdp.split('\n')
        const mLineIndex = lines.findIndex(line => line.startsWith('m='))
        if (mLineIndex !== -1) {
          lines.splice(mLineIndex, 0, 'a=group:BUNDLE 0')
          sdp = lines.join('\n')
        }
      }
      
      const modifiedOffer = new RTCSessionDescription({
        type: 'offer',
        sdp: sdp
      })
      
      await pc.setLocalDescription(modifiedOffer)
    
    // 使用简化的API调用
    const response = await fetch(buildUrls.srsApi('/rtc/v1/play/'), {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        streamurl: streamUrl,
        sdp: sdp
      })
    })
    
    console.log('SRS响应状态:', response.status)
    
    if (response.ok) {
      const data = await response.json()
      console.log('SRS响应数据:', data)
      
      if (data.code === 0) {
        await pc.setRemoteDescription(new RTCSessionDescription({
          type: 'answer',
          sdp: data.sdp
        }))
        console.log('✅ 测试连接成功')
      } else {
        console.error('❌ SRS返回错误:', data)
      }
    } else {
      console.error('❌ HTTP错误:', response.status)
    }
    
  } catch (error) {
    console.error('❌ 测试失败:', error)
  }
}

// WebRTC连接方法 - 参考WebRTCStreamView.vue的快速连接方式
const connectWebRTC = async () => {
  try {
    isLoading.value = true
    connectionStatus.value = '连接中...'
    
    console.log('🚀 快速WebRTC连接启动...')
    
    if (!mainVideo.value) return
    const video = mainVideo.value
    
    // 创建RTCPeerConnection
    const pc = new RTCPeerConnection({
      iceServers: [
        { urls: 'stun:stun.l.google.com:19302' },
        { urls: 'stun:stun1.l.google.com:19302' }
      ]
    })
    
    // 添加接收轨道，这样SDP才会包含媒体信息
    pc.addTransceiver('video', { direction: 'recvonly' })
    pc.addTransceiver('audio', { direction: 'recvonly' })
    
    webrtcConnection.value = pc
    
    // 处理远程流
    pc.ontrack = async (event) => {
      console.log('收到远程流:', event.streams[0])
      console.log('设置视频流到video元素...')
      video.srcObject = event.streams[0]
      
      // 使用安全播放函数，参考WebRTCStreamView.vue
      await safePlayVideo(video, { muted: false })
      handleVideoCanPlay()
    }
    
    // 处理ICE连接状态
    pc.oniceconnectionstatechange = () => {
      console.log('ICE连接状态:', pc.iceConnectionState)
      if (pc.iceConnectionState === 'connected') {
        connectionStatus.value = '已连接'
        isLoading.value = false
      } else if (pc.iceConnectionState === 'failed') {
        handleVideoError()
      }
    }
    
      // 创建offer
      const offer = await pc.createOffer()
      
      // 修改SDP以支持BUNDLE
      let sdp = offer.sdp
      if (!sdp.includes('a=group:BUNDLE')) {
        // 添加BUNDLE组
        const lines = sdp.split('\n')
        const mLineIndex = lines.findIndex(line => line.startsWith('m='))
        if (mLineIndex !== -1) {
          lines.splice(mLineIndex, 0, 'a=group:BUNDLE 0')
          sdp = lines.join('\n')
        }
      }
      
      const modifiedOffer = new RTCSessionDescription({
        type: 'offer',
        sdp: sdp
      })
      
      await pc.setLocalDescription(modifiedOffer)
    
    // 使用正确的SRS WebRTC API格式
    const requestData = {
      api: buildUrls.srsApi('/rtc/v1/play/'),
      streamurl: buildUrls.webrtc(),
      sdp: offer.sdp
    }
    
    console.log('发送到SRS的请求数据:', requestData)
    
    // 使用SRS自带播放器的API端点
    const apiEndpoints = [
      buildUrls.srsApi('/rtc/v1/play/')
    ]
    
    let response = null
    let lastError = null
    
    for (const endpoint of apiEndpoints) {
      try {
        console.log(`尝试API端点: ${endpoint}`)
        
        response = await fetch(endpoint, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(requestData)
        })
        
        console.log(`API端点 ${endpoint} 响应状态:`, response.status)
        
        if (response.ok) {
          const data = await response.json()
          console.log(`API端点 ${endpoint} 响应数据:`, data)
          
          if (data.code === 0) {
            console.log('✅ SRS服务器返回成功，设置远程描述...')
            await pc.setRemoteDescription(new RTCSessionDescription({
              type: 'answer',
              sdp: data.sdp
            }))
            console.log(`✅ API端点 ${endpoint} 连接成功`)
            return // 成功连接，退出函数
          } else {
            console.error(`❌ SRS服务器返回错误: code=${data.code}, message=${data.message || '未知错误'}`)
            lastError = new Error(`API端点 ${endpoint} 响应错误: ${data.code} - ${data.message || '未知错误'}`)
          }
        } else {
          const errorText = await response.text()
          console.error(`❌ HTTP错误: ${response.status}, 响应: ${errorText}`)
          lastError = new Error(`API端点 ${endpoint} HTTP错误: ${response.status} - ${errorText}`)
        }
      } catch (error) {
        console.error(`API端点 ${endpoint} 请求失败:`, error)
        lastError = error
      }
    }
    
    // 如果WebRTC连接失败，显示连接提示
    console.log('WebRTC连接失败...')
    connectionStatus.value = '连接失败'
    errorMessage.value = `WebRTC连接失败

🔧 推流配置：
- 服务器：${buildUrls.rtmp()}
- 串流密钥：${config.srs.rtmp.streamName}
- 播放URL：${buildUrls.webrtc()}
- 录制URL：${buildUrls.webrtcRecord()}`
    hasError.value = true
    isLoading.value = false
    
  } catch (error) {
    console.error('WebRTC连接失败:', error)
    // WebRTC失败时，尝试备用连接方法（也优先WebRTC）
    tryConnectAlternative()
  }
}

// 备用连接方法
const tryConnectAlternative = async () => {
  try {
    console.log('🔄 尝试备用WebRTC连接方法...')
    isLoading.value = true
    connectionStatus.value = '重试WebRTC连接...'
    
    // 优先尝试WebRTC连接
    await connectWebRTC()
    return
    
    if (!mainVideo.value) return
    const video = mainVideo.value
    
    // 创建RTCPeerConnection
    const pc = new RTCPeerConnection({
      iceServers: [
        { urls: 'stun:stun.l.google.com:19302' },
        { urls: 'stun:stun1.l.google.com:19302' }
      ]
    })
    
    // 添加接收轨道，这样SDP才会包含媒体信息
    pc.addTransceiver('video', { direction: 'recvonly' })
    pc.addTransceiver('audio', { direction: 'recvonly' })
    
    webrtcConnection.value = pc
    
    // 处理远程流
    pc.ontrack = async (event) => {
      console.log('收到远程流:', event.streams[0])
      console.log('设置视频流到video元素...')
      video.srcObject = event.streams[0]
      
      // 使用安全播放函数，参考WebRTCStreamView.vue
      await safePlayVideo(video, { muted: false })
      handleVideoCanPlay()
    }
    
    // 处理ICE连接状态
    pc.oniceconnectionstatechange = () => {
      console.log('ICE连接状态:', pc.iceConnectionState)
      if (pc.iceConnectionState === 'connected') {
        connectionStatus.value = '已连接'
        isLoading.value = false
      } else if (pc.iceConnectionState === 'failed') {
        handleVideoError()
      }
    }
    
      // 创建offer
      const offer = await pc.createOffer()
      
      // 修改SDP以支持BUNDLE
      let sdp = offer.sdp
      if (!sdp.includes('a=group:BUNDLE')) {
        // 添加BUNDLE组
        const lines = sdp.split('\n')
        const mLineIndex = lines.findIndex(line => line.startsWith('m='))
        if (mLineIndex !== -1) {
          lines.splice(mLineIndex, 0, 'a=group:BUNDLE 0')
          sdp = lines.join('\n')
        }
      }
      
      const modifiedOffer = new RTCSessionDescription({
        type: 'offer',
        sdp: sdp
      })
      
      await pc.setLocalDescription(modifiedOffer)
    
    // 尝试使用不同的流地址格式
    const streamUrls = [
      buildUrls.webrtc(),
      buildUrls.webrtc().replace(':1985', ':1985'),
      buildUrls.rtmp()
    ]
    
    for (const streamUrl of streamUrls) {
      try {
        console.log(`尝试流地址: ${streamUrl}`)
        
        const response = await fetch(buildUrls.srsApi('/rtc/v1/play/'), {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            streamurl: streamUrl,
            sdp: offer.sdp
          })
        })
        
        console.log(`流地址 ${streamUrl} 响应状态:`, response.status)
        
        if (response.ok) {
          const data = await response.json()
          console.log(`流地址 ${streamUrl} 响应数据:`, data)
          
          if (data.code === 0) {
            await pc.setRemoteDescription(new RTCSessionDescription({
              type: 'answer',
              sdp: data.sdp
            }))
            console.log(`流地址 ${streamUrl} 连接成功`)
            return // 成功连接，退出循环
          }
        }
      } catch (error) {
        console.error(`流地址 ${streamUrl} 连接失败:`, error)
      }
    }
    
    throw new Error('所有流地址都连接失败')
    
  } catch (error) {
    console.error('备用连接方法也失败:', error)
    // 尝试使用HLS流作为最后的备用方案
    tryHLSStream()
  }
}

// 添加连接计数器，防止无限循环
const connectionAttempts = ref(0)
const maxConnectionAttempts = 3

// 视频流监控
const videoMonitorInterval = ref(null)
const backgroundConnectionInterval = ref(null)

// 启动视频监控工作线程
const startVideoMonitoringWorker = () => {
  console.log('🚀 启动视频监控工作线程...')
  isVideoMonitoringActive.value = true
  
  videoMonitoringWorker.value = setInterval(() => {
    // 只有在明确停止时才退出，而不是检查isVideoMonitoringActive
    if (mainVideo.value && connectionStatus.value === '已连接') {
      const video = mainVideo.value
      
      // 检查视频是否有流 - 更宽松的检查
      if (!video.srcObject && !video.src) {
        console.log('⚠️ 视频没有流，尝试恢复...')
        // 先尝试强制恢复视频流
        if (!forceRestoreVideoStream()) {
          // 如果恢复失败，延迟重连
          setTimeout(() => {
            if (!video.srcObject && !video.src) {
              console.log('🔄 强制恢复失败，尝试重新连接...')
              autoConnectVideoStream()
            }
          }, 2000)
        }
        return
      }
      
      // 检查视频是否暂停
      if (video.paused && video.readyState >= 2) {
        console.log('⚠️ 视频暂停了，尝试播放...')
        video.play().catch(error => {
          console.error('❌ 视频播放失败:', error)
        })
      }
      
      // 检查视频是否卡住 - 更严格的检查
      if (video.readyState >= 2 && video.currentTime > 0) {
        const lastTime = video.currentTime
        setTimeout(() => {
          if (video.currentTime === lastTime && !video.paused && video.readyState >= 2) {
            console.log('⚠️ 视频可能卡住了，尝试重新连接...')
            autoConnectVideoStream()
          }
        }, 10000) // 延长检查时间到10秒
      }
    }
  }, 5000) // 延长检查间隔到5秒
}

// 停止视频监控工作线程
const stopVideoMonitoringWorker = () => {
  console.log('⏹️ 停止视频监控工作线程...')
  isVideoMonitoringActive.value = false
  
  if (videoMonitoringWorker.value) {
    clearInterval(videoMonitoringWorker.value)
    videoMonitoringWorker.value = null
  }
}

// 开始视频流监控（兼容旧方法）
const startVideoMonitoring = () => {
  startVideoMonitoringWorker()
}

// 停止视频流监控
const stopVideoMonitoring = () => {
  stopVideoMonitoringWorker()
  
  if (videoMonitorInterval.value) {
    clearInterval(videoMonitorInterval.value)
    videoMonitorInterval.value = null
  }
}

// 开始后台连接保持
const startBackgroundConnection = () => {
  if (backgroundConnectionInterval.value) {
    clearInterval(backgroundConnectionInterval.value)
  }
  
  backgroundConnectionInterval.value = setInterval(() => {
    // 检查连接状态，如果断开则尝试重连
    if (!checkVideoConnectionStatus() && activeTab.value === 'monitor') {
      console.log('🔄 检测到连接断开，尝试重连...')
      autoConnectVideoStream()
    }
  }, 5000) // 每5秒检查一次
}

// 停止后台连接保持
const stopBackgroundConnection = () => {
  if (backgroundConnectionInterval.value) {
    clearInterval(backgroundConnectionInterval.value)
    backgroundConnectionInterval.value = null
  }
}

// 检查视频流连接状态
const checkVideoConnectionStatus = () => {
  if (!mainVideo.value) return false
  
  const video = mainVideo.value
  const hasStream = !!(video.srcObject || video.src)
  const isConnected = connectionStatus.value === '已连接'
  const hasWebRTCConnection = !!webrtcConnection.value
  const hasVideoContent = video.videoWidth > 0 && video.videoHeight > 0
  
  console.log('视频连接状态检查:', {
    hasStream,
    isConnected,
    hasWebRTCConnection,
    videoPaused: video.paused,
    videoReadyState: video.readyState,
    hasVideoContent,
    videoWidth: video.videoWidth,
    videoHeight: video.videoHeight
  })
  
  // 更宽松的连接状态检查，只要有WebRTC连接就认为连接正常
  return isConnected && hasWebRTCConnection
}

// FLV流连接方案
const tryFLVStream = async () => {
  console.log('🎬 尝试FLV流连接...')
  
  if (!mainVideo.value) return
  const video = mainVideo.value
  
  // 尝试FLV流地址
  const flvUrls = [
    buildUrls.flv('livestream'),
    `${config.srs.hls.baseUrl}/live/livestream/index.flv`,
    `${config.srs.hls.baseUrl}/livestream.flv`
  ]
  
  for (const flvUrl of flvUrls) {
    try {
      console.log(`尝试FLV流: ${flvUrl}`)
      video.src = flvUrl
      video.load()
      
      // 等待加载完成
      await new Promise((resolve, reject) => {
        const timeout = setTimeout(() => {
          reject(new Error('FLV流加载超时'))
        }, 5000)
        
        video.onloadeddata = () => {
          clearTimeout(timeout)
          resolve()
        }
        
        video.onerror = () => {
          clearTimeout(timeout)
          reject(new Error('FLV流加载失败'))
        }
      })
      
      console.log('✅ FLV流连接成功')
      connectionStatus.value = '已连接'
      errorMessage.value = ''
      hasError.value = false
      isLoading.value = false
      return
      
    } catch (error) {
      console.log(`FLV流 ${flvUrl} 连接失败:`, error.message)
    }
  }
  
  console.log('❌ 所有FLV流都连接失败')
  connectionStatus.value = '连接失败'
  errorMessage.value = 'FLV流连接失败，请检查SRS服务器配置'
  hasError.value = true
  isLoading.value = false
}

// HLS流连接方案
const tryHLSStream = async () => {
  try {
    console.log('尝试HLS流连接...')
    
    // 检查连接次数
    if (connectionAttempts.value >= maxConnectionAttempts) {
      console.log('已达到最大连接尝试次数，停止连接')
      connectionStatus.value = '连接失败'
      errorMessage.value = '连接尝试次数过多，请检查SRS服务器配置'
      hasError.value = true
      isLoading.value = false
      return
    }
    
    connectionAttempts.value++
    console.log(`连接尝试次数: ${connectionAttempts.value}/${maxConnectionAttempts}`)
    
    // 先检查服务器状态
    const serverStatus = await checkSRSServer()
    if (serverStatus && serverStatus.streams && serverStatus.streams.streams) {
      const activeStreams = serverStatus.streams.streams
      if (activeStreams.length === 0) {
        console.warn('⚠️ 没有活跃的流，无法连接HLS')
        connectionStatus.value = '等待推流...'
        errorMessage.value = '服务器上没有活跃的视频流，请确保推流设备正在工作'
        hasError.value = true
        isLoading.value = false
        return
      }
      
      // 检查HTTP服务器配置
      if (serverStatus.config && serverStatus.config.data && serverStatus.config.data.http_server) {
        const httpConfig = serverStatus.config.data.http_server
        console.log('HTTP服务器配置:', httpConfig)
        
        if (httpConfig.enabled && httpConfig.listen) {
          const httpPort = httpConfig.listen.split(':')[1] || '8080'
          console.log(`HTTP服务器运行在端口: ${httpPort}`)
        }
      }
      
      // 检查HLS配置
      if (serverStatus.config && serverStatus.config.data && serverStatus.config.data.hls) {
        const hlsConfig = serverStatus.config.data.hls
        console.log('HLS配置:', hlsConfig)
        
        if (!hlsConfig.enabled) {
          console.warn('⚠️ HLS未启用，无法使用HLS流')
          console.log('🔄 尝试使用WebRTC连接...')
          // 不直接返回错误，而是尝试WebRTC
          return await connectWebRTC()
        } else {
          console.log('✅ HLS已启用，配置:', hlsConfig)
        }
      } else {
        console.warn('⚠️ 无法获取HLS配置信息')
        console.log('🔄 尝试使用FLV流连接...')
        // 不直接返回错误，而是尝试FLV流
        return await tryFLVStream()
      }
      
      // 检查vhost配置中的HLS设置
      if (serverStatus.config && serverStatus.config.data && serverStatus.config.data.vhost) {
        const vhostConfig = serverStatus.config.data.vhost
        console.log('VHost配置:', vhostConfig)
        
        if (vhostConfig.hls) {
          console.log('VHost HLS配置:', vhostConfig.hls)
        }
      }
      
      // 显示完整的SRS配置信息
      console.log('📋 完整SRS配置信息:')
      console.log('服务器信息:', {
        server: serverStatus.config.data.server,
        service: serverStatus.config.data.service,
        pid: serverStatus.config.data.pid
      })
      
      // 检查所有可用的模块
      const modules = serverStatus.config.data.modules || []
      console.log('已加载模块:', modules)
      
      // 检查是否有HLS模块
      const hasHLSModule = modules.some(module => module.name === 'hls' || module.name === 'HLS')
      console.log('HLS模块状态:', hasHLSModule ? '✅ 已加载' : '❌ 未加载')
      
      // 检查WebRTC模块
      const hasWebRTCModule = modules.some(module => module.name === 'webrtc' || module.name === 'WebRTC')
      console.log('WebRTC模块状态:', hasWebRTCModule ? '✅ 已加载' : '❌ 未加载')
    }
    
    
    if (!mainVideo.value) return
    const video = mainVideo.value
    
    // 获取流名称
    let streamName = 'livestream' // 默认流名称
    if (serverStatus && serverStatus.streams && serverStatus.streams.streams && serverStatus.streams.streams.length > 0) {
      const stream = serverStatus.streams.streams[0]
      streamName = stream.name || stream.stream || 'livestream'
      console.log(`使用流名称: ${streamName}`)
      
      // 检查流的详细信息
      console.log('流详细信息:', stream)
      if (stream.urls) {
        console.log('流URL信息:', stream.urls)
      }
      
      // 检查推流状态
      if (stream.publish) {
        console.log('✅ 推流状态:', stream.publish)
        if (stream.publish.active) {
          console.log('✅ 推流正在进行中')
        } else {
          console.warn('⚠️ 推流未激活，可能推流已停止')
        }
      } else {
        console.warn('⚠️ 无法获取推流状态')
      }
    }
    
    // 测试SRS服务器的实际HLS路径
    console.log('🔍 测试SRS服务器HLS路径...')
    const testPaths = [
      `${config.srs.hls.baseUrl}/`,
      `${config.srs.hls.baseUrl}/live/`,
      `${config.srs.hls.baseUrl}/live/livestream/`,
      `${config.srs.hls.baseUrl}/live/livestream/index.html`,
      // 尝试其他可能的HLS路径
      `${config.srs.hls.baseUrl}/hls/`,
      `${config.srs.hls.baseUrl}/hls/livestream/`,
      `${config.srs.hls.baseUrl}/streams/`,
      `${config.srs.hls.baseUrl}/streams/livestream/`,
      `${config.srs.hls.baseUrl}/vod/`,
      `${config.srs.hls.baseUrl}/vod/livestream/`
    ]
    
    for (const testPath of testPaths) {
      try {
        const response = await fetch(testPath, { method: 'HEAD' })
        console.log(`测试路径 ${testPath}: ${response.status}`)
        if (response.status === 200) {
          console.log(`✅ 找到可访问的路径: ${testPath}`)
        }
      } catch (error) {
        console.log(`测试路径 ${testPath}: 无法访问`)
      }
    }
    
    // 尝试直接访问HLS文件
    console.log('🔍 测试HLS文件路径...')
    const hlsTestPaths = [
      buildUrls.hls('livestream', '/live'),
      buildUrls.hls('livestream', '/hls'),
      buildUrls.hls('livestream', '/streams'),
      buildUrls.hls('livestream', '/vod'),
      buildUrls.hls('livestream')
    ]
    
    for (const hlsPath of hlsTestPaths) {
      try {
        const response = await fetch(hlsPath, { method: 'HEAD' })
        console.log(`测试HLS文件 ${hlsPath}: ${response.status}`)
        if (response.status === 200) {
          console.log(`✅ 找到HLS文件: ${hlsPath}`)
        }
      } catch (error) {
        console.log(`测试HLS文件 ${hlsPath}: 无法访问`)
      }
    }
    
    // 扩展流地址列表，包含所有可能的HLS路径
    const streamUrls = [
      // 正确的HLS格式（已验证可用）
      buildUrls.hls(streamName, '/live'),
      // 其他可能的格式
      buildUrls.hls(streamName, '/hls'),
      buildUrls.hls(streamName, '/streams'),
      buildUrls.hls(streamName, '/vod'),
      // 根路径
      buildUrls.hls(streamName),
      // 其他可能的文件名
      `${config.srs.hls.baseUrl}/live/${streamName}/playlist.m3u8`,
      `${config.srs.hls.baseUrl}/live/${streamName}/live.m3u8`
    ]
    
    let currentIndex = 0
    
    const tryNextStream = () => {
      if (currentIndex >= streamUrls.length) {
        console.error('所有流地址都尝试失败')
        
        // 提供详细的错误诊断信息
        const errorDetails = `
❌ 视频流连接失败

🔍 诊断结果：
- ✅ 推流正在进行：${streamName} 流已激活
- ❌ HLS模块未启用：SRS服务器未配置HLS功能
- ❌ 所有HLS路径返回404：无法找到.m3u8文件

🛠️ 解决方案：

1. 启用SRS的HLS模块：
   - 访问SRS管理界面：${buildUrls.srsApi('')}
   - 检查配置文件中的hls模块设置
   - 确保HLS模块已启用并正确配置

2. 使用WebRTC连接（推荐）：
   - 当前推流支持WebRTC协议
   - 尝试使用WebRTC播放器连接

3. 配置HLS路径：
   - 检查SRS配置中的hls_path设置
   - 确保HLS文件生成路径正确

4. 验证推流格式：
   - 播放URL：${buildUrls.webrtc()}
   - 录制URL：${buildUrls.webrtcRecord()}
   - 确保推流格式与播放格式匹配
        `
        
        console.error(errorDetails)
        
        connectionStatus.value = '连接失败'
        errorMessage.value = `视频流连接失败

🔧 推流配置：
- 服务器：${buildUrls.rtmp()}
- 串流密钥：${config.srs.rtmp.streamName}
- 播放URL：${buildUrls.webrtc()}
- 录制URL：${buildUrls.webrtcRecord()}`
        hasError.value = true
        isLoading.value = false
        return
      }
      
      const streamUrl = streamUrls[currentIndex]
      console.log(`尝试流地址 ${currentIndex + 1}/${streamUrls.length}: ${streamUrl}`)
      
      video.src = streamUrl
      video.load()
      
      // 设置超时
      const timeout = setTimeout(() => {
        console.log(`流地址 ${streamUrl} 超时`)
        currentIndex++
        tryNextStream()
      }, 5000)
      
      video.oncanplay = () => {
        clearTimeout(timeout)
        console.log(`流地址 ${streamUrl} 连接成功`)
        handleVideoCanPlay()
      }
      
      video.onerror = (e) => {
        clearTimeout(timeout)
        console.log(`流地址 ${streamUrl} 连接失败:`, e)
        currentIndex++
        tryNextStream()
      }
    }
    
    tryNextStream()
    
  } catch (error) {
    console.error('HLS流连接失败:', error)
    handleVideoError()
  }
}




const logout = () => {
  sysUser.uid = ''
  sysUser.username = ''
  router.push('/login')
}

const goToSlamManager = () => {
  router.push('/slam-manager')
}

const updateCurrentTime = () => {
  const now = new Date()
  currentTime.value = now.toLocaleTimeString('zh-CN', { 
    hour12: false,
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

const updateDashboardData = () => {
  // 模拟数据更新
  console.log('更新监控数据')
}

const initChart = () => {
  // 初始化图表
  console.log('初始化图表')
}

// 全屏状态监听
const handleFullscreenChange = () => {
  const wasFullscreen = isFullscreen.value
  isFullscreen.value = !!document.fullscreenElement
  
  console.log('全屏状态变化:', isFullscreen.value, '控制按钮状态:', showControls.value)
  
  // 如果刚进入全屏，显示提示和控制栏
  if (isFullscreen.value && !wasFullscreen) {
    showFullscreenTip.value = true
    showControls.value = true // 进入全屏时显示控制栏
    console.log('进入全屏，显示控制栏')
    setTimeout(() => {
      showFullscreenTip.value = false
    }, 3000)
  }
  
  // 确保全屏模式下控制栏始终可见
  if (isFullscreen.value) {
    showControls.value = true
  }
  
  // 退出全屏时隐藏控制按钮
  if (!isFullscreen.value) {
    showControls.value = false
    if (controlsTimer.value) {
      clearTimeout(controlsTimer.value)
      controlsTimer.value = null
    }
  }
}

// 控制按钮显示/隐藏逻辑
const showControlsTemporarily = () => {
  if (!isFullscreen.value) return
  
  console.log('显示控制按钮')
  showControls.value = true
  
  // 清除之前的定时器
  if (controlsTimer.value) {
    clearTimeout(controlsTimer.value)
  }
  
  // 5秒后自动隐藏（延长显示时间）
  controlsTimer.value = setTimeout(() => {
    console.log('隐藏控制按钮')
    showControls.value = false
    controlsTimer.value = null
  }, 5000)
}

// 切换控制栏显示/隐藏
const toggleControls = () => {
  console.log('点击切换控制栏按钮，当前状态:', showControls.value)
  showControls.value = !showControls.value
  console.log('切换后控制栏显示状态:', showControls.value)
  
  // 设置用户手动隐藏标志
  if (!showControls.value) {
    userManuallyHidden.value = true
    console.log('用户手动隐藏控制栏')
  } else {
    userManuallyHidden.value = false
    console.log('用户手动显示控制栏')
  }
  
  // 如果显示控制栏，清除自动隐藏定时器
  if (showControls.value && controlsTimer.value) {
    clearTimeout(controlsTimer.value)
    controlsTimer.value = null
    console.log('清除自动隐藏定时器')
  }
}

// 点击视频区域显示控制按钮
const handleVideoClick = () => {
  console.log('视频点击事件，全屏状态:', isFullscreen.value)
  if (isFullscreen.value) {
    // 点击视频区域总是显示控制栏，重置手动隐藏标志
    showControls.value = true
    userManuallyHidden.value = false
    showControlsTemporarily()
  }
}

// 鼠标移动时显示控制按钮
const handleVideoMouseMove = () => {
  if (isFullscreen.value) {
    // 如果用户手动隐藏了控制栏，鼠标移动时不自动显示
    if (userManuallyHidden.value) {
      return
    }
    
    // 只有在控制栏已经显示时才自动隐藏
    if (showControls.value) {
    showControlsTemporarily()
    }
  }
}

// 键盘快捷键处理
const handleKeydown = (event) => {
  // ESC键退出全屏
  if (event.key === 'Escape' && isFullscreen.value) {
    toggleFullscreen()
  }
  // F键进入全屏
  if (event.key === 'f' || event.key === 'F') {
    if (!isFullscreen.value) {
      toggleFullscreen()
    }
  }
  // 空格键播放/暂停
  if (event.key === ' ') {
    event.preventDefault()
    togglePlayPause()
  }
}

// 监听路由变化
watch(() => props.defaultTab, (newTab) => {
  if (newTab) {
    activeTab.value = newTab
  }
}, { immediate: true })

// 生命周期
onMounted(() => {
  updateCurrentTime()
  setInterval(updateCurrentTime, 1000)
  setInterval(updateDashboardData, 10000)
  initChart()
  
  // 监听全屏状态变化
  document.addEventListener('fullscreenchange', handleFullscreenChange)
  document.addEventListener('webkitfullscreenchange', handleFullscreenChange)
  document.addEventListener('mozfullscreenchange', handleFullscreenChange)
  document.addEventListener('MSFullscreenChange', handleFullscreenChange)
  
  // 监听键盘事件
  document.addEventListener('keydown', handleKeydown)
  
  // 添加点击外部关闭音量控制
  document.addEventListener('click', handleClickOutside)
  
  // 启动连接流程
  console.log('🚀 启动视频流连接...')
  
  // 启动视频监控工作线程
  startVideoMonitoringWorker()
  
  // 启动视频流保持机制
  startVideoStreamKeepAlive()
  
  // 自动连接视频流
  autoConnectVideoStream()
  
  // 启动后台连接保持
  startBackgroundConnection()
  
  // 监听标签切换
  watch(activeTab, (newTab) => {
    if (newTab === 'recordings') {
      // 切换到回放标签时，保持视频监控运行，启动录制回放工作线程
      console.log('📹 切换到回放标签，保持视频监控运行，启动录制回放工作线程...')
      // 不停止视频监控工作线程，保持视频流连接
      startRecordingPlaybackWorker() // 启动录制回放工作线程
      
      // 默认加载今天的录像和时间段
      selectedDate.value = new Date().toISOString().split('T')[0]
      loadRecordingsByDate(selectedDate.value)
    } else if (newTab === 'monitor') {
      // 切换到监控标签时，暂停录制回放，确保视频监控工作线程运行
      console.log('📺 切换到监控标签，确保视频监控工作线程运行...')
      stopRecordingPlaybackWorker() // 暂停录制回放工作线程
      
      // 确保视频监控工作线程正在运行
      if (!isVideoMonitoringActive.value) {
        console.log('🔄 视频监控工作线程未运行，启动中...')
        startVideoMonitoringWorker()
      }
      
      // 重置手动隐藏标志，允许自动显示控制栏
      userManuallyHidden.value = false
      
      // 检查视频连接状态
      if (checkVideoConnectionStatus()) {
        // 如果视频还在连接，尝试恢复视频流
        console.log('✅ 视频流仍然连接，尝试恢复视频流...')
        
        // 尝试强制恢复视频流
        if (!forceRestoreVideoStream()) {
          console.log('📺 保持现有视频流连接...')
        }
      } else {
        // 如果视频断开，重新连接
        console.log('🔄 视频流已断开，重新连接...')
        setTimeout(() => {
          autoConnectVideoStream(true) // 强制重连
        }, 100)
      }
    }
  })
})

// 组件卸载时清理事件监听
onUnmounted(() => {
  document.removeEventListener('fullscreenchange', handleFullscreenChange)
  document.removeEventListener('webkitfullscreenchange', handleFullscreenChange)
  document.removeEventListener('mozfullscreenchange', handleFullscreenChange)
  document.removeEventListener('MSFullscreenChange', handleFullscreenChange)
  document.removeEventListener('keydown', handleKeydown)
  document.removeEventListener('click', handleClickOutside)

  // 清理控制按钮定时器
  if (controlsTimer.value) {
    clearTimeout(controlsTimer.value)
    controlsTimer.value = null
  }
  
  // 停止工作线程
  stopVideoMonitoringWorker()
  stopRecordingPlaybackWorker()
  
  // 清理人脸识别定时器
  stopFaceDetection()
  
  // 清理YOLO检测定时器
  stopYOLODetection()
  
  // 停止视频流保持机制
  stopVideoStreamKeepAlive()
  
  // 停止视频流监控
  stopVideoMonitoring()
  
  // 停止后台连接保持
  stopBackgroundConnection()

  // 停止流监控
  stopStreamMonitoring()

  // 清理WebRTC连接
  if (webrtcConnection.value) {
    webrtcConnection.value.close()
    webrtcConnection.value = null
  }
})
</script>

<style scoped>
@import url('https://cdn.tailwindcss.com');
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css');
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');

/* Tailwind CSS通过CDN加载 */

@layer utilities {
  .scrollbar-hide {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
  .scrollbar-hide::-webkit-scrollbar {
    display: none;
  }
  .card-shadow {
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1), 0 4px 20px rgba(0, 0, 0, 0.05);
  }
  .hover-scale {
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  }
  .hover-scale:hover {
    transform: scale(1.02) translateY(-2px);
  }
  .animate-pulse-slow {
    animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
  }
  .animate-fade-in {
    animation: fadeIn 0.6s ease-out;
  }
  .animate-slide-up {
    animation: slideUp 0.5s ease-out;
  }
  .animate-bounce-gentle {
    animation: bounceGentle 2s ease-in-out infinite;
  }
  .glass-effect {
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.2);
  }
  .gradient-border {
    position: relative;
    background: linear-gradient(white, white) padding-box,
                linear-gradient(45deg, #3b82f6, #8b5cf6) border-box;
    border: 2px solid transparent;
  }
  @keyframes fadeIn {
    from { 
      opacity: 0; 
      transform: translateY(20px);
    }
    to { 
      opacity: 1; 
      transform: translateY(0);
    }
  }
  @keyframes slideUp {
    from { 
      opacity: 0; 
      transform: translateY(30px);
    }
    to { 
      opacity: 1; 
      transform: translateY(0);
    }
  }
  @keyframes bounceGentle {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-5px); }
  }
  @keyframes shimmer {
    0% { background-position: -200px 0; }
    100% { background-position: calc(200px + 100%) 0; }
  }
  .shimmer {
    background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
    background-size: 200px 100%;
    animation: shimmer 1.5s infinite;
  }
}

/* 确保表格响应式 */
.overflow-x-auto {
  overflow-x: auto;
}

/* 确保按钮样式正确 */
button {
  cursor: pointer;
}

/* 确保输入框样式正确 */
input, select, textarea {
  font-family: inherit;
}

/* 确保链接样式正确 */
a {
  text-decoration: none;
}

/* 确保图片响应式 */
img {
  max-width: 100%;
  height: auto;
}

/* 确保SVG正确显示 */
svg {
  display: block;
}

/* 确保Canvas正确显示 */
canvas {
  display: block;
}

/* 自定义滚动条 */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.1);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: linear-gradient(45deg, #3b82f6, #8b5cf6);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(45deg, #2563eb, #7c3aed);
}

/* 视频播放器美化 */
video {
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}

/* 按钮悬停效果增强 */
button {
  position: relative;
  overflow: hidden;
}

button::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
  transition: left 0.5s;
}

button:hover::before {
  left: 100%;
}

/* 卡片悬停效果 */
.card-hover {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.card-hover:hover {
  transform: translateY(-4px) scale(1.02);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
}

/* 渐变文字效果 */
.gradient-text {
  background: linear-gradient(45deg, #3b82f6, #8b5cf6, #ec4899);
  background-size: 200% 200%;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  animation: gradientShift 3s ease infinite;
}

@keyframes gradientShift {
  0% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* 状态指示器动画 */
.status-indicator {
  position: relative;
}

.status-indicator::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: inherit;
  transform: translate(-50%, -50%);
  animation: ripple 2s infinite;
}

@keyframes ripple {
  0% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) scale(2);
    opacity: 0;
  }
}

/* 全屏模式样式 */
.video-container.fullscreen-mode {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  width: 100vw !important;
  height: 100vh !important;
  z-index: 9999 !important;
  background: #000 !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}

.video-container.fullscreen-mode .aspect-video {
  width: 100% !important;
  height: 100% !important;
  aspect-ratio: unset !important;
  border-radius: 0 !important;
}

.video-container.fullscreen-mode video {
  width: 100% !important;
  height: 100% !important;
  object-fit: contain !important;
  border-radius: 0 !important;
}

/* 全屏模式下的控制栏 */
.video-container.fullscreen-mode .video-controls {
  position: fixed !important;
  bottom: 0 !important;
  left: 0 !important;
  right: 0 !important;
  background: rgba(0, 0, 0, 0.8) !important;
  backdrop-filter: blur(10px) !important;
  z-index: 10000 !important;
  transition: opacity 0.3s ease !important;
  width: 100vw !important;
  height: auto !important;
}

/* 全屏模式下控制栏隐藏状态 */
.video-container.fullscreen-mode .video-controls.opacity-0 {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* 全屏模式下控制栏显示状态 */
.video-container.fullscreen-mode .video-controls.opacity-100 {
  opacity: 1 !important;
  pointer-events: auto !important;
}

/* 全屏模式下的状态指示器 */
.video-container.fullscreen-mode .absolute {
  z-index: 10001 !important;
}

/* 全屏模式下的加载和错误状态 */
.video-container.fullscreen-mode .absolute.inset-0 {
  background: #000 !important;
  z-index: 10002 !important;
}

/* 全屏模式下的人脸识别覆盖层 */
.video-container.fullscreen-mode .absolute.inset-0.pointer-events-none {
  z-index: 10010 !important;
  background: transparent !important;
}

/* 全屏模式下的人脸框 */
.video-container.fullscreen-mode .absolute.border-2 {
  z-index: 10011 !important;
}

/* 全屏模式下隐藏右侧用户面板 */
.video-container.fullscreen-mode ~ .w-80 {
  display: none !important;
}

/* 全屏模式下隐藏flex容器中的用户面板 */
.video-container.fullscreen-mode + .w-80 {
  display: none !important;
}

/* 全屏模式下的加载状态简化 */
.loading-fullscreen {
  z-index: 10003 !important;
}

/* 音量滑块样式 */
.slider {
  -webkit-appearance: none;
  appearance: none;
}

/* 竖直音量滑块样式 */
.slider-vertical {
  writing-mode: vertical-lr;
  direction: rtl;
  transform: rotate(0deg);
  width: 8px;
  height: 128px;
  background: rgba(209, 213, 219, 0.8);
  border-radius: 4px;
  outline: none;
  cursor: pointer;
  backdrop-filter: blur(4px);
}


.slider-vertical::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  background: rgba(59, 130, 246, 0.9);
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(4px);
  border: 2px solid rgba(255, 255, 255, 0.3);
}

.slider-vertical::-moz-range-thumb {
  width: 20px;
  height: 20px;
  background: rgba(59, 130, 246, 0.9);
  border-radius: 50%;
  cursor: pointer;
  border: 2px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(4px);
}

.slider::-webkit-slider-track {
  background: #d1d5db;
  height: 4px;
  border-radius: 2px;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  background: #3b82f6;
  height: 16px;
  width: 16px;
  border-radius: 50%;
  cursor: pointer;
  border: 2px solid #ffffff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.slider::-webkit-slider-thumb:hover {
  background: #2563eb;
  transform: scale(1.1);
}

.slider::-moz-range-track {
  background: #d1d5db;
  height: 4px;
  border-radius: 2px;
  border: none;
}

.slider::-moz-range-thumb {
  background: #3b82f6;
  height: 16px;
  width: 16px;
  border-radius: 50%;
  cursor: pointer;
  border: 2px solid #ffffff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.slider::-moz-range-thumb:hover {
  background: #2563eb;
  transform: scale(1.1);
}

.loading-fullscreen .text-center {
  z-index: 10004 !important;
}

/* 全屏模式下的提示信息 */
.video-container.fullscreen-mode .absolute.top-4.right-4 {
  z-index: 10006 !important;
  background: rgba(0, 0, 0, 0.9) !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
}

/* 全屏模式下的快捷键提示 - 右下角边缘，避免遮挡 */
.video-container.fullscreen-mode .absolute.bottom-24.right-2 {
  z-index: 10006 !important;
  background: rgba(0, 0, 0, 0.9) !important;
  border: 1px solid rgba(255, 255, 255, 0.2) !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.6) !important;
  font-weight: 500 !important;
  font-size: 10px !important;
  padding: 4px 8px !important;
}

/* 全屏模式下的状态指示器层级 */
.video-container.fullscreen-mode .absolute.top-4.left-4,
.video-container.fullscreen-mode .absolute.bottom-4.left-4,
.video-container.fullscreen-mode .absolute.bottom-4.right-4 {
  z-index: 10005 !important;
  background: rgba(0, 0, 0, 0.9) !important;
  border: 1px solid rgba(255, 255, 255, 0.2) !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.6) !important;
}

/* 全屏模式右上角边缘提示 */
.video-container.fullscreen-mode .absolute.top-24.right-2 {
  z-index: 10007 !important;
  background: rgba(0, 0, 0, 0.95) !important;
  border: 1px solid rgba(255, 255, 255, 0.3) !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.6) !important;
  font-size: 10px !important;
  padding: 4px 8px !important;
}

/* 全屏模式下的最小化ESC提示 */
.video-container.fullscreen-mode .absolute.top-2.right-2 {
  z-index: 10008 !important;
  background: rgba(0, 0, 0, 0.5) !important;
  font-size: 10px !important;
  padding: 2px 4px !important;
  border-radius: 4px !important;
}


@keyframes segmentShine {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* 监控系统卡片样式 */
.surveillance-card {
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
}

.surveillance-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, #3b82f6, #8b5cf6, #ec4899);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.surveillance-card:hover {
  transform: translateY(-4px) scale(1.02);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
  border-color: #3b82f6;
}

.surveillance-card:hover::before {
  opacity: 1;
}

/* 监控状态指示器 */
.status-indicator {
  position: relative;
  display: inline-block;
}

.status-indicator::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: inherit;
  transform: translate(-50%, -50%);
  animation: statusPulse 2s ease-in-out infinite;
}

@keyframes statusPulse {
  0% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) scale(2);
    opacity: 0;
  }
}

/* 监控按钮样式 */
.surveillance-button {
  position: relative;
  overflow: hidden;
  background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
  border: none;
  border-radius: 8px;
  color: white;
  font-weight: 600;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3);
}

.surveillance-button::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
  transition: left 0.5s ease;
}

.surveillance-button:hover::before {
  left: 100%;
}

.surveillance-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(59, 130, 246, 0.4);
}

/* 监控数据统计样式 */
.stats-card {
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  padding: 1.5rem;
  text-align: center;
  position: relative;
  overflow: hidden;
  transition: all 0.3s ease;
}

.stats-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, #3b82f6, #8b5cf6, #ec4899);
}

.stats-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}

.stats-number {
  font-size: 2rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
  background: linear-gradient(135deg, #3b82f6, #8b5cf6);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.stats-label {
  font-size: 0.875rem;
  color: #64748b;
  font-weight: 500;
}


/* 今天按钮特殊样式 */
.today-button {
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
  box-shadow: 0 2px 8px rgba(16, 185, 129, 0.3);
}

.today-button:hover {
  background: linear-gradient(135deg, #059669 0%, #047857 100%);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
}

/* 录像缩略图样式 */
.recording-thumbnail {
  position: relative;
  background: linear-gradient(135deg, #1f2937 0%, #111827 100%);
  border-radius: 8px;
  overflow: hidden;
  transition: all 0.3s ease;
}

.recording-thumbnail::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(45deg, transparent 30%, rgba(59, 130, 246, 0.1) 50%, transparent 70%);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.recording-thumbnail:hover::before {
  opacity: 1;
}

.recording-thumbnail:hover {
  transform: scale(1.05);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
}

/* 播放按钮悬停效果 */
.play-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: all 0.3s ease;
  backdrop-filter: blur(2px);
}

.recording-thumbnail:hover .play-overlay {
  opacity: 1;
}

.play-button {
  width: 80px;
  height: 80px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #1f2937;
  font-size: 2rem;
  transition: all 0.3s ease;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
}

.play-button:hover {
  background: white;
  transform: scale(1.1);
  box-shadow: 0 6px 30px rgba(0, 0, 0, 0.3);
}

/* YOLO置信度阈值滑块样式 */
.slider::-webkit-slider-thumb {
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #8b5cf6;
  cursor: pointer;
  border: 2px solid white;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

.slider::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #8b5cf6;
  cursor: pointer;
  border: 2px solid white;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

/* 响应式设计 */
@media (max-width: 768px) {
  
  .stats-card {
    padding: 1rem;
  }
  
  .stats-number {
    font-size: 1.5rem;
  }
  
  .surveillance-card {
    margin-bottom: 1rem;
  }
}
</style>
